28 : type_(other.type_), data_(other.data_)
30 if (other.geometry_set_) {
31 geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_);
40 geometry_set_->ensure_owns_direct_data();
49 return geometry_set_->owns_direct_data();
56 geometry_set_->count_memory(memory);
79 transform.location() +=
float3(collection_child->collection->instance_offset);
81 const int handle = instances.
add_reference(*collection_child->collection);
88 transform *= (collection_object->ob)->object_to_world();
89 const int handle = instances.
add_reference(*collection_object->ob);
96 r_geometry_set.
clear();
105 std::unique_ptr<bke::Instances> instances_ptr = std::make_unique<bke::Instances>();
137 if (a.geometry_set_ &&
b.geometry_set_) {
138 return *a.geometry_set_ == *
b.geometry_set_;
140 return a.type_ ==
b.type_ && a.data_ ==
b.data_;
145 const uint64_t geometry_hash = geometry_set_ ? geometry_set_->hash() : 0;
152 : references_(std::move(other.references_)),
153 instances_num_(other.instances_num_),
154 attributes_(std::move(other.attributes_)),
155 reference_user_counts_(std::move(other.reference_user_counts_)),
156 unique_ids_cache_(std::move(other.unique_ids_cache_))
161 : references_(other.references_),
162 instances_num_(other.instances_num_),
163 attributes_(other.attributes_),
164 reference_user_counts_(other.reference_user_counts_),
165 unique_ids_cache_(other.unique_ids_cache_)
173 if (
this == &other) {
176 std::destroy_at(
this);
183 if (
this == &other) {
186 std::destroy_at(
this);
195 instances_num_ = capacity;
196 if (capacity > old_size) {
207 BLI_assert(instance_handle < references_.size());
247 return references_[reference_index].geometry_set();
252 for (
const int i : references_.index_range()) {
254 if (reference == query) {
272 return references_.append_and_get_index(reference);
287 const std::optional<IndexRange> masked_range =
mask.to_range();
288 if (masked_range.has_value() && masked_range->start() == 0) {
296 new_instances.references_ = std::move(references_);
297 new_instances.instances_num_ =
mask.size();
306 *
this = std::move(new_instances);
313 const int tot_instances = instances_num_;
314 const int tot_references_before = references_.size();
316 if (tot_instances == 0) {
321 if (tot_references_before == 1) {
329 Array<bool> usage_by_handle(tot_references_before,
false);
335 Array<bool> local_usage_by_handle(tot_references_before,
false);
337 for (
const int i : range) {
339 BLI_assert(handle >= 0 && handle < tot_references_before);
340 local_usage_by_handle[handle] =
true;
344 for (
const int i :
IndexRange(tot_references_before)) {
345 usage_by_handle[
i] |= local_usage_by_handle[
i];
349 if (!usage_by_handle.
as_span().contains(
false)) {
357 int next_new_handle = 0;
358 bool handles_have_to_be_updated =
false;
359 for (
const int old_handle :
IndexRange(tot_references_before)) {
360 if (!usage_by_handle[old_handle]) {
362 handle_mapping.
append(-1);
366 handle_mapping.
append(next_new_handle);
367 new_references.
append(reference);
368 if (old_handle != next_new_handle) {
369 handles_have_to_be_updated =
true;
374 references_ = new_references;
376 if (!handles_have_to_be_updated) {
386 for (
const int i : range) {
395 return this->instances_num_;
400 return references_.
size();
406 if (!reference.owns_direct_data()) {
425 attributes_.count_memory(memory);
427 reference.count_memory(memory);
438 for (
const int instance_index : original_ids.
index_range()) {
439 const int original_id = original_ids[instance_index];
440 if (used_unique_ids.
add(original_id)) {
442 unique_ids[instance_index] = original_id;
448 instances_with_id_collision.
append(instance_index);
453 for (
const int instance_index : instances_with_id_collision) {
454 const int original_id = original_ids[instance_index];
461 const int max_iteration = 100;
462 for (
int iteration = 0;; iteration++) {
465 if (used_unique_ids.
add(random_id)) {
467 unique_ids[instance_index] = random_id;
470 if (iteration == max_iteration) {
475 if (used_unique_ids.
add(generated_id)) {
476 unique_ids[instance_index] = generated_id;
490 reference_user_counts_.ensure([&](
Array<int> &r_data) {
496 for (
const int handle :
handles) {
502 return reference_user_counts_.
data();
507 unique_ids_cache_.ensure([&](
Array<int> &r_data) {
516 return unique_ids_cache_.
data();
#define LISTBASE_FOREACH(type, var, list)
Object groups, one object can be in many groups at once.
Object is a sort of wrapper for general info.
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
unsigned long long int uint64_t
constexpr T & last(const int64_t n=0) const
constexpr const T * data() const
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
void fill(const T &value) const
void reinitialize(const int64_t new_size)
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
void seed_random(uint32_t seed)
void reserve(const int64_t n)
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
static VArray from_derived_span(Span< StructT > values)
static VMutableArray from_derived_span(MutableSpan< StructT > values)
void append(const T &value)
GAttributeReader lookup(const StringRef attribute_id) const
void count_memory(MemoryCounter &memory) const
void ensure_owns_direct_data()
void to_geometry_set(GeometrySet &r_geometry_set) const
GeometrySet & geometry_set()
StringRefNull name() const
bool owns_direct_data() const
InstanceReference()=default
Collection & collection() const
Span< int > reference_handles() const
void ensure_owns_direct_data()
MutableSpan< int > reference_handles_for_write()
int add_reference(const InstanceReference &reference)
void remove(const IndexMask &mask, const AttributeFilter &attribute_filter)
int add_new_reference(const InstanceReference &reference)
GeometrySet & geometry_set_from_reference(int reference_index)
Span< float4x4 > transforms() const
void add_instance(int instance_handle, const float4x4 &transform)
Span< InstanceReference > references() const
Span< int > reference_user_counts() const
Instances & operator=(const Instances &other)
void resize(int capacity)
int references_num() const
bke::MutableAttributeAccessor attributes_for_write()
bke::AttributeAccessor attributes() const
MutableSpan< InstanceReference > references_for_write()
void tag_reference_handles_changed()
void remove_unused_references()
int instances_num() const
void count_memory(MemoryCounter &memory) const
bool owns_direct_data() const
std::optional< int > find_reference_handle(const InstanceReference &query)
MutableSpan< float4x4 > transforms_for_write()
Span< int > unique_ids() const
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void fill_index_range(MutableSpan< T > span, const T start=0)
static void convert_collection_to_instances(const Collection &collection, bke::Instances &instances)
GMutableSpan get_mutable_attribute(AttributeStorage &storage, const AttrDomain domain, const CPPType &cpp_type, const StringRef name, const int64_t domain_size, const void *custom_default_value)
void fill_attribute_range_default(MutableAttributeAccessor dst_attributes, AttrDomain domain, const AttributeFilter &attribute_filter, IndexRange range)
std::optional< GSpan > get_span_attribute(const AttributeStorage &storage, const AttrDomain domain, const CPPType &cpp_type, const StringRef name, const int64_t domain_size)
bool operator==(const InstanceReference &a, const InstanceReference &b)
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static float3 get_transform_position(const float4x4 &transform)
GeometrySet object_get_evaluated_geometry_set(const Object &object, bool apply_subdiv=true)
VArray< float3 > instance_position_varray(const Instances &instances)
static Array< int > generate_unique_instance_ids(Span< int > original_ids)
VMutableArray< float3 > instance_position_varray_for_write(Instances &instances)
static void set_transform_position(float4x4 &transform, const float3 position)
const AttributeAccessorFunctions & instance_attribute_accessor_functions()
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
MatBase< float, 4, 4 > float4x4
uint64_t get_default_hash(const T &v, const Args &...args)
VecBase< float, 3 > float3
static MatBase identity()
void replace_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)