Blender V5.0
foreach_geometry.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BKE_geometry_set.hh"
6#include "BKE_instances.hh"
7
10
11namespace blender::geometry {
12
15 Vector<int> &path,
16 Map<bke::GeometrySet, Vector<Vector<int>>> &r_real_geometries)
17{
18 bke::GeometrySet real_geometry = geometry;
21
22 r_real_geometries.lookup_or_add_default(std::move(real_geometry)).append(path);
23
24 bke::Instances *instances = geometry.get_instances_for_write();
25 if (!instances) {
26 return;
27 }
28 instances->ensure_geometry_instances();
30 for (const int i : references.index_range()) {
31 bke::InstanceReference &reference = references[i];
33 bke::GeometrySet &sub_geometry = reference.geometry_set();
34 path.append(i);
35 extract_real_geometries_recursive(sub_geometry, path, r_real_geometries);
36 path.pop_last();
37 }
38 }
39}
40
42 const bke::GeometrySet &geometry_to_insert,
43 const Span<int> path)
44{
45 if (path.is_empty()) {
46 /* Instance references must not be merged here as that could invalidate the paths. */
47 const bool allow_merging_instance_references = false;
48 /* Important to pass the old geometry first, so that the instance reference paths stay
49 * valid. */
51 {geometry, geometry_to_insert}, {}, {}, allow_merging_instance_references);
52 return;
53 }
54 bke::Instances *instances = geometry.get_instances_for_write();
55 BLI_assert(instances);
56 const int reference_i = path.first();
57 const MutableSpan<bke::InstanceReference> references = instances->references_for_write();
58 BLI_assert(reference_i < references.size());
59 bke::InstanceReference &reference = references[reference_i];
61 bke::GeometrySet &sub_geometry = reference.geometry_set();
62 reinsert_modified_geometry_recursive(sub_geometry, geometry_to_insert, path.drop_front(1));
63}
64
69
71 FunctionRef<void(bke::GeometrySet &geometry_set)> fn)
72{
73 /* Afterwards the geometry does not have realized geometry anymore. It has been extracted and
74 * will be reinserted afterwards. */
76 {
77 Vector<int> path;
78 extract_real_geometries_recursive(geometry, path, real_geometries);
79 }
80 /* Take the geometries out of the map so that they can be edited in-place. As keys in the #Map
81 * the geometries are const and thus can't be modified. */
82 Vector<GeometryWithPaths> geometries_with_paths;
83 for (auto &&item : real_geometries.items()) {
84 geometries_with_paths.append({item.key, std::move(item.value)});
85 }
86 /* Clear to avoid extra references to the geometries which prohibit editing them in-place. */
87 real_geometries.clear();
88
89 /* Actually modify the geometries in parallel. */
90 threading::parallel_for(geometries_with_paths.index_range(), 1, [&](const IndexRange range) {
91 for (const int i : range) {
92 bke::GeometrySet &geometry_to_modify = geometries_with_paths[i].geometry;
93 fn(geometry_to_modify);
94 }
95 });
96
97 /* Reinsert modified geometries. */
98 for (GeometryWithPaths &geometry_with_paths : geometries_with_paths) {
99 for (const Span<int> path : geometry_with_paths.paths) {
100 reinsert_modified_geometry_recursive(geometry, geometry_with_paths.geometry, path);
101 }
102 }
103}
104
105} // namespace blender::geometry
#define BLI_assert(a)
Definition BLI_assert.h:46
void clear()
Definition BLI_map.hh:1038
ItemIterator items() const &
Definition BLI_map.hh:902
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr IndexRange index_range() const
Definition BLI_span.hh:670
constexpr Span drop_front(int64_t n) const
Definition BLI_span.hh:171
constexpr const T & first() const
Definition BLI_span.hh:315
constexpr bool is_empty() const
Definition BLI_span.hh:260
void append(const T &value)
IndexRange index_range() const
MutableSpan< InstanceReference > references_for_write()
Definition instances.cc:280
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt, bool allow_merging_instance_references=true)
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
static void reinsert_modified_geometry_recursive(bke::GeometrySet &geometry, const bke::GeometrySet &geometry_to_insert, const Span< int > path)
static void extract_real_geometries_recursive(bke::GeometrySet &geometry, Vector< int > &path, Map< bke::GeometrySet, Vector< Vector< int > > > &r_real_geometries)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
void remove(const GeometryComponent::Type component_type)
i
Definition text_draw.cc:230