46 new_component->instance_reference_handles_ = instance_reference_handles_;
47 new_component->instance_transforms_ = instance_transforms_;
48 new_component->references_ = references_;
49 new_component->attributes_ = attributes_;
55 instance_reference_handles_.
reserve(min_capacity);
56 instance_transforms_.
reserve(min_capacity);
62 instance_reference_handles_.
resize(capacity);
63 instance_transforms_.
resize(capacity);
69 instance_reference_handles_.
clear();
70 instance_transforms_.
clear();
79 instance_reference_handles_.
append(instance_handle);
86 return instance_reference_handles_;
91 return instance_reference_handles_;
96 return instance_transforms_;
100 return instance_transforms_;
111 return const_cast<GeometrySet &
>(references_[reference_index].geometry_set());
130 for (const int i : range) {
131 dst[i] = src[mask[i]];
139 if (
mask.is_range() &&
mask.as_range().start() == 0) {
148 instance_reference_handles_ = std::move(new_handles);
151 instance_transforms_ = std::move(new_transforms);
160 if (!
id.should_be_kept()) {
169 using T = decltype(dummy);
170 copy_data_based_on_mask<T>(src.typed<T>(), dst.typed<T>(), mask);
176 attributes_ = std::move(dst_attributes);
186 const int tot_references_before = references_.size();
188 if (tot_instances == 0) {
193 if (tot_references_before == 1) {
199 Array<bool> usage_by_handle(tot_references_before,
false);
205 Array<bool> local_usage_by_handle(tot_references_before,
false);
207 for (
const int i : range) {
208 const int handle = instance_reference_handles_[i];
209 BLI_assert(handle >= 0 && handle < tot_references_before);
210 local_usage_by_handle[handle] =
true;
214 for (
const int i :
IndexRange(tot_references_before)) {
215 usage_by_handle[i] |= local_usage_by_handle[i];
219 if (!usage_by_handle.
as_span().contains(
false)) {
227 int next_new_handle = 0;
228 bool handles_have_to_be_updated =
false;
229 for (
const int old_handle :
IndexRange(tot_references_before)) {
230 if (!usage_by_handle[old_handle]) {
232 handle_mapping.
append(-1);
236 handle_mapping.
append(next_new_handle);
237 new_references.
add_new(reference);
238 if (old_handle != next_new_handle) {
239 handles_have_to_be_updated =
true;
244 references_ = new_references;
246 if (!handles_have_to_be_updated) {
254 for (
const int i : range) {
255 instance_reference_handles_[i] = handle_mapping[instance_reference_handles_[i]];
262 return instance_transforms_.size();
267 return references_.size();
272 return this->instance_reference_handles_.size() == 0;
278 if (!reference.owns_direct_data()) {
304 for (
const int instance_index : original_ids.
index_range()) {
305 const int original_id = original_ids[instance_index];
306 if (used_unique_ids.
add(original_id)) {
308 unique_ids[instance_index] = original_id;
314 instances_with_id_collision.
append(instance_index);
319 for (
const int instance_index : instances_with_id_collision) {
320 const int original_id = original_ids[instance_index];
327 const int max_iteration = 100;
328 for (
int iteration = 0;; iteration++) {
331 if (used_unique_ids.
add(random_id)) {
333 unique_ids[instance_index] = random_id;
336 if (iteration == max_iteration) {
340 unique_ids[instance_index] = original_id;
351 std::lock_guard
lock(almost_unique_ids_mutex_);
352 std::optional<GSpan> instance_ids_gspan = attributes_.get_for_read(
"id");
353 if (instance_ids_gspan) {
354 Span<int> instance_ids = instance_ids_gspan->typed<
int>();
355 if (almost_unique_ids_.size() != instance_ids.
size()) {
361 for (
const int i : almost_unique_ids_.index_range()) {
362 almost_unique_ids_[i] = i;
365 return almost_unique_ids_;
370 return this->attributes_;
375 return this->attributes_;
444 [](
const void *owner) ->
int {
460 BuiltinAttributeProvider::Creatable,
461 BuiltinAttributeProvider::Writable,
462 BuiltinAttributeProvider::Deletable,
463 instance_custom_data_access,
464 make_array_read_attribute<int>,
465 make_array_write_attribute<int>,
469 instance_custom_data_access);
478 attribute_accessor_functions::accessor_functions_for_providers<providers>();
480 if (owner ==
nullptr) {
@ GEO_COMPONENT_TYPE_INSTANCES
MINLINE void copy_v3_v3(float r[3], const float a[3])
Object groups, one object can be in many groups at once.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Map
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
GeometryComponentType type() const
void ensure_owns_direct_data()
blender::Span< int > instance_reference_handles() const
int references_num() const
blender::bke::CustomDataAttributes & instance_attributes()
std::optional< blender::bke::AttributeAccessor > attributes() const final
void remove_unused_references()
std::optional< blender::bke::MutableAttributeAccessor > attributes_for_write() final
blender::Span< int > almost_unique_ids() const
int add_reference(const InstanceReference &reference)
GeometrySet & geometry_set_from_reference(int reference_index)
blender::Span< InstanceReference > references() const
GeometryComponent * copy() const override
bool owns_direct_data() const override
void resize(int capacity)
void add_instance(int instance_handle, const blender::float4x4 &transform)
blender::MutableSpan< blender::float4x4 > instance_transforms()
bool is_empty() const final
void remove_instances(const blender::IndexMask mask)
void ensure_owns_direct_data() override
int instances_num() const
void reserve(int min_capacity)
Span< T > as_span() const
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
constexpr T * data() const
void seed_random(uint32_t seed)
void reserve(const int64_t n)
constexpr int64_t size() const
constexpr IndexRange index_range() const
int64_t index_of_or_add_as(ForwardKey &&key)
void add_new(const Key &key)
void append(const T &value)
void resize(const int64_t new_size)
void reserve(const int64_t min_capacity)
std::optional< blender::GSpan > get_for_read(const AttributeIDRef &attribute_id) const
bool create(const AttributeIDRef &attribute_id, eCustomDataType data_type)
std::optional< blender::GMutableSpan > get_for_write(const AttributeIDRef &attribute_id)
void reallocate(int size)
bool foreach_attribute(const AttributeForeachCallback callback, eAttrDomain domain) const
GVArray try_get_for_read(const void *owner) const final
bool exists(const void *UNUSED(owner)) const final
GAttributeWriter try_get_for_write(void *owner) const final
bool try_delete(void *UNUSED(owner)) const final
InstancePositionAttributeProvider()
bool try_create(void *UNUSED(owner), const AttributeInit &UNUSED(initializer)) const final
SyclQueue void void * src
BLI_CPP_TYPE_MAKE(GeometrySet, GeometrySet, CPPTypeFlags::Printable)
static void copy_data_based_on_mask(Span< T > src, MutableSpan< T > dst, IndexMask mask)
static blender::Array< int > generate_unique_instance_ids(Span< int > original_ids)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
static float3 get_transform_position(const float4x4 &transform)
static ComponentAttributeProviders create_attribute_providers_for_instances()
static const AttributeAccessorFunctions & get_instances_accessor_functions_ref()
static AttributeAccessorFunctions get_instances_accessor_functions()
static void set_transform_position(float4x4 &transform, const float3 position)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
bool(* domain_supported)(const void *owner, eAttrDomain domain)
GVArray(* adapt_domain)(const void *owner, const GVArray &varray, eAttrDomain from_domain, eAttrDomain to_domain)
int(* domain_size)(const void *owner, eAttrDomain domain)