24 geometry_set_(std::make_unique<
GeometrySet>(std::move(geometry_set)))
29 : type_(other.type_), data_(other.data_)
31 if (other.geometry_set_) {
32 geometry_set_ = std::make_unique<GeometrySet>(*other.geometry_set_);
41 geometry_set_->ensure_owns_direct_data();
50 return geometry_set_->owns_direct_data();
57 geometry_set_->count_memory(memory);
70 transform.location() +=
float3(collection_child->collection->instance_offset);
71 transform.location() -=
float3(collection.instance_offset);
72 const int handle = instances.add_reference(*collection_child->collection);
73 instances.add_instance(handle, transform);
78 transform.location() -=
float3(collection.instance_offset);
79 transform *= (collection_object->ob)->object_to_world();
80 const int handle = instances.add_reference(*collection_object->ob);
81 instances.add_instance(handle, transform);
87 r_geometry_set.
clear();
96 std::unique_ptr<bke::Instances> instances_ptr = std::make_unique<bke::Instances>();
128 if (a.geometry_set_ &&
b.geometry_set_) {
129 return *a.geometry_set_ == *
b.geometry_set_;
131 return a.type_ ==
b.type_ && a.data_ ==
b.data_;
136 const uint64_t geometry_hash = geometry_set_ ? geometry_set_->hash() : 0;
146 : references_(std::move(other.references_)),
147 instances_num_(other.instances_num_),
148 attributes_(other.attributes_),
149 reference_user_counts_(std::move(other.reference_user_counts_)),
150 almost_unique_ids_cache_(std::move(other.almost_unique_ids_cache_))
156 : references_(other.references_),
157 instances_num_(other.instances_num_),
158 reference_user_counts_(other.reference_user_counts_),
159 almost_unique_ids_cache_(other.almost_unique_ids_cache_)
171 if (
this == &other) {
174 std::destroy_at(
this);
181 if (
this == &other) {
184 std::destroy_at(
this);
192 instances_num_ = capacity;
198 BLI_assert(instance_handle < references_.size());
199 const int old_size = instances_num_;
209 return {
static_cast<const int *
>(
217 &attributes_,
CD_PROP_INT32,
".reference_index", instances_num_));
222 return {
data, instances_num_};
227 return {
static_cast<const float4x4 *
>(
240 return {
data, instances_num_};
249 return references_[reference_index].geometry_set();
254 for (
const int i : references_.index_range()) {
256 if (reference == query) {
274 return references_.append_and_get_index(reference);
284 const std::optional<IndexRange> masked_range = mask.to_range();
285 if (masked_range.has_value() && masked_range->start() == 0) {
293 new_instances.references_ = std::move(references_);
294 new_instances.instances_num_ = mask.size();
303 *
this = std::move(new_instances);
310 const int tot_instances = instances_num_;
311 const int tot_references_before = references_.size();
313 if (tot_instances == 0) {
318 if (tot_references_before == 1) {
326 Array<bool> usage_by_handle(tot_references_before,
false);
332 Array<bool> local_usage_by_handle(tot_references_before,
false);
334 for (
const int i :
range) {
336 BLI_assert(handle >= 0 && handle < tot_references_before);
337 local_usage_by_handle[handle] =
true;
341 for (
const int i :
IndexRange(tot_references_before)) {
342 usage_by_handle[i] |= local_usage_by_handle[i];
346 if (!usage_by_handle.
as_span().contains(
false)) {
354 int next_new_handle = 0;
355 bool handles_have_to_be_updated =
false;
356 for (
const int old_handle :
IndexRange(tot_references_before)) {
357 if (!usage_by_handle[old_handle]) {
359 handle_mapping.
append(-1);
363 handle_mapping.
append(next_new_handle);
364 new_references.
append(reference);
365 if (old_handle != next_new_handle) {
366 handles_have_to_be_updated =
true;
371 references_ = new_references;
373 if (!handles_have_to_be_updated) {
383 for (
const int i :
range) {
392 return this->instances_num_;
397 return references_.size();
403 if (!reference.owns_direct_data()) {
424 reference.count_memory(memory);
435 for (
const int instance_index : original_ids.
index_range()) {
436 const int original_id = original_ids[instance_index];
437 if (used_unique_ids.
add(original_id)) {
439 unique_ids[instance_index] = original_id;
445 instances_with_id_collision.
append(instance_index);
450 for (
const int instance_index : instances_with_id_collision) {
451 const int original_id = original_ids[instance_index];
458 const int max_iteration = 100;
459 for (
int iteration = 0;; iteration++) {
462 if (used_unique_ids.
add(random_id)) {
464 unique_ids[instance_index] = random_id;
467 if (iteration == max_iteration) {
471 unique_ids[instance_index] = original_id;
482 reference_user_counts_.ensure([&](
Array<int> &r_data) {
488 for (
const int handle :
handles) {
494 return reference_user_counts_.data();
499 almost_unique_ids_cache_.ensure([&](
Array<int> &r_data) {
501 if (instance_ids_attribute) {
502 Span<int> instance_ids = instance_ids_attribute.
varray.get_internal_span();
503 if (r_data.
size() != instance_ids.
size()) {
512 return almost_unique_ids_cache_.data();
517 return transform.location();
522 transform.location() = position;
CustomData interface, see also DNA_customdata_types.h.
void CustomData_count_memory(const CustomData &data, int totelem, blender::MemoryCounter &memory)
void CustomData_realloc(CustomData *data, int old_size, int new_size, eCDAllocType alloctype=CD_CONSTRUCT)
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_reset(CustomData *data)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_free(CustomData *data, int totelem)
#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
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
void fill(const T &value) const
void reinitialize(const int64_t new_size)
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
constexpr T & last(const int64_t n=0) const
void seed_random(uint32_t seed)
void reserve(const int64_t n)
constexpr int64_t size() const
constexpr IndexRange index_range() const
static VArray ForDerivedSpan(Span< StructT > values)
static VMutableArray ForDerivedSpan(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
void tag_reference_handles_changed()
void remove_unused_references()
int instances_num() const
void count_memory(MemoryCounter &memory) const
Span< int > almost_unique_ids() const
bool owns_direct_data() const
std::optional< int > find_reference_handle(const InstanceReference &query)
MutableSpan< float4x4 > transforms_for_write()
local_group_size(16, 16) .push_constant(Type b
void fill_index_range(MutableSpan< T > span, const T start=0)
static void convert_collection_to_instances(const Collection &collection, bke::Instances &instances)
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)
GeometrySet object_get_evaluated_geometry_set(const Object &object)
static float3 get_transform_position(const float4x4 &transform)
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)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
uint64_t get_default_hash(const T &v)
VecBase< float, 3 > float3
unsigned __int64 uint64_t
static MatBase identity()
void replace_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)