Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenloader/intern/versioning_300.c13
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc154
3 files changed, 50 insertions, 119 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 899d21683e4..32b607ecf9b 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 36
+#define BLENDER_FILE_SUBVERSION 37
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 51a3e32f2bb..bdee5194c9a 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -754,6 +754,19 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 300, 37)) {
+ LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
+ if (node->type == GEO_NODE_BOUNDING_BOX) {
+ bNodeSocket *geometry_socket = node->inputs.first;
+ add_realize_instances_before_socket(ntree, node, geometry_socket);
+ }
+ }
+ }
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
index 8b90595a641..e34b65e6c94 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
@@ -14,9 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "BKE_spline.hh"
-#include "BKE_volume.h"
-
#include "node_geometry_util.hh"
namespace blender::nodes {
@@ -29,135 +26,56 @@ static void geo_node_bounding_box_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>("Max");
}
-using bke::GeometryInstanceGroup;
-
-static void compute_min_max_from_position_and_transform(const GeometryComponent &component,
- Span<float4x4> transforms,
- float3 &r_min,
- float3 &r_max)
-{
- GVArray_Typed<float3> positions = component.attribute_get_for_read<float3>(
- "position", ATTR_DOMAIN_POINT, {0, 0, 0});
-
- for (const float4x4 &transform : transforms) {
- for (const int i : positions.index_range()) {
- const float3 position = positions[i];
- const float3 transformed_position = transform * position;
- minmax_v3v3_v3(r_min, r_max, transformed_position);
- }
- }
-}
-
-static void compute_min_max_from_volume_and_transforms(const VolumeComponent &volume_component,
- Span<float4x4> transforms,
- float3 &r_min,
- float3 &r_max)
-{
-#ifdef WITH_OPENVDB
- const Volume *volume = volume_component.get_for_read();
- if (volume == nullptr) {
- return;
- }
- for (const int i : IndexRange(BKE_volume_num_grids(volume))) {
- const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, i);
- openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
-
- for (const float4x4 &transform : transforms) {
- openvdb::GridBase::ConstPtr instance_grid = BKE_volume_grid_shallow_transform(grid,
- transform);
- float3 grid_min = float3(FLT_MAX);
- float3 grid_max = float3(-FLT_MAX);
- if (BKE_volume_grid_bounds(instance_grid, grid_min, grid_max)) {
- DO_MIN(grid_min, r_min);
- DO_MAX(grid_max, r_max);
- }
- }
- }
-#else
- UNUSED_VARS(volume_component, transforms, r_min, r_max);
-#endif
-}
-
-static void compute_min_max_from_curve_and_transforms(const CurveComponent &curve_component,
- Span<float4x4> transforms,
- float3 &r_min,
- float3 &r_max)
-{
- const CurveEval *curve = curve_component.get_for_read();
- if (curve == nullptr) {
- return;
- }
- for (const SplinePtr &spline : curve->splines()) {
- Span<float3> positions = spline->evaluated_positions();
-
- for (const float4x4 &transform : transforms) {
- for (const int i : positions.index_range()) {
- const float3 position = positions[i];
- const float3 transformed_position = transform * position;
- minmax_v3v3_v3(r_min, r_max, transformed_position);
- }
- }
- }
-}
-
-static void compute_geometry_set_instances_boundbox(const GeometrySet &geometry_set,
- float3 &r_min,
- float3 &r_max)
-{
- Vector<GeometryInstanceGroup> set_groups;
- bke::geometry_set_gather_instances(geometry_set, set_groups);
-
- for (const GeometryInstanceGroup &set_group : set_groups) {
- const GeometrySet &set = set_group.geometry_set;
- Span<float4x4> transforms = set_group.transforms;
-
- if (set.has<PointCloudComponent>()) {
- compute_min_max_from_position_and_transform(
- *set.get_component_for_read<PointCloudComponent>(), transforms, r_min, r_max);
- }
- if (set.has<MeshComponent>()) {
- compute_min_max_from_position_and_transform(
- *set.get_component_for_read<MeshComponent>(), transforms, r_min, r_max);
- }
- if (set.has<VolumeComponent>()) {
- compute_min_max_from_volume_and_transforms(
- *set.get_component_for_read<VolumeComponent>(), transforms, r_min, r_max);
- }
- if (set.has<CurveComponent>()) {
- compute_min_max_from_curve_and_transforms(
- *set.get_component_for_read<CurveComponent>(), transforms, r_min, r_max);
- }
- }
-}
-
static void geo_node_bounding_box_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+ /* Compute the min and max of all realized geometry for the two
+ * vector outputs, which are only meant to consider real geometry. */
float3 min = float3(FLT_MAX);
float3 max = float3(-FLT_MAX);
-
- if (geometry_set.has_instances()) {
- compute_geometry_set_instances_boundbox(geometry_set, min, max);
- }
- else {
- geometry_set.compute_boundbox_without_instances(&min, &max);
- }
-
+ geometry_set.compute_boundbox_without_instances(&min, &max);
if (min == float3(FLT_MAX)) {
- params.set_output("Bounding Box", GeometrySet());
params.set_output("Min", float3(0));
params.set_output("Max", float3(0));
}
else {
- const float3 scale = max - min;
- const float3 center = min + scale / 2.0f;
- Mesh *mesh = create_cuboid_mesh(scale, 2, 2, 2);
- transform_mesh(*mesh, center, float3(0), float3(1));
- params.set_output("Bounding Box", GeometrySet::create_with_mesh(mesh));
params.set_output("Min", min);
params.set_output("Max", max);
}
+
+ /* Generate the bounding box meshes inside each unique geometry set (including individually for
+ * every instance). Because geometry components are reference counted anyway, we can just
+ * repurpose the original geometry sets for the output. */
+ if (params.output_is_required("Bounding Box")) {
+ geometry_set.modify_geometry_sets([&](GeometrySet &sub_geometry) {
+ float3 sub_min = float3(FLT_MAX);
+ float3 sub_max = float3(-FLT_MAX);
+
+ /* Reuse the min and max calculation if this is the main "real" geometry set. */
+ if (&sub_geometry == &geometry_set) {
+ sub_min = min;
+ sub_max = max;
+ }
+ else {
+ sub_geometry.compute_boundbox_without_instances(&sub_min, &sub_max);
+ }
+
+ if (sub_min == float3(FLT_MAX)) {
+ sub_geometry.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
+ }
+ else {
+ const float3 scale = sub_max - sub_min;
+ const float3 center = sub_min + scale / 2.0f;
+ Mesh *mesh = create_cuboid_mesh(scale, 2, 2, 2);
+ transform_mesh(*mesh, center, float3(0), float3(1));
+ sub_geometry.replace_mesh(mesh);
+ sub_geometry.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES});
+ }
+ });
+
+ params.set_output("Bounding Box", std::move(geometry_set));
+ }
}
} // namespace blender::nodes