Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/geometry_component_instances.cc
| Show All 11 Lines | |||||
| * You should have received a copy of the GNU General Public License | * You should have received a copy of the GNU General Public License | ||||
| * along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
| */ | */ | ||||
| #include <mutex> | #include <mutex> | ||||
| #include "BLI_float4x4.hh" | #include "BLI_float4x4.hh" | ||||
| #include "BLI_index_mask.hh" | |||||
| #include "BLI_map.hh" | #include "BLI_map.hh" | ||||
| #include "BLI_rand.hh" | #include "BLI_rand.hh" | ||||
| #include "BLI_set.hh" | #include "BLI_set.hh" | ||||
| #include "BLI_span.hh" | #include "BLI_span.hh" | ||||
| #include "BLI_task.hh" | #include "BLI_task.hh" | ||||
| #include "BLI_vector.hh" | #include "BLI_vector.hh" | ||||
| #include "DNA_collection_types.h" | #include "DNA_collection_types.h" | ||||
| #include "BKE_attribute_access.hh" | |||||
| #include "BKE_attribute_math.hh" | |||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||
| #include "BKE_geometry_set_instances.hh" | #include "BKE_geometry_set_instances.hh" | ||||
| #include "attribute_access_intern.hh" | #include "attribute_access_intern.hh" | ||||
| #include "FN_cpp_type_make.hh" | #include "FN_cpp_type_make.hh" | ||||
| using blender::float4x4; | using blender::float4x4; | ||||
| using blender::IndexMask; | |||||
| using blender::Map; | using blender::Map; | ||||
| using blender::MutableSpan; | using blender::MutableSpan; | ||||
| using blender::Set; | using blender::Set; | ||||
| using blender::Span; | using blender::Span; | ||||
| using blender::VectorSet; | using blender::VectorSet; | ||||
| using blender::fn::GSpan; | using blender::fn::GSpan; | ||||
| MAKE_CPP_TYPE(InstanceReference, InstanceReference, CPPTypeFlags::None) | MAKE_CPP_TYPE(InstanceReference, InstanceReference, CPPTypeFlags::None) | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | int InstancesComponent::add_reference(const InstanceReference &reference) | ||||
| return references_.index_of_or_add_as(reference); | return references_.index_of_or_add_as(reference); | ||||
| } | } | ||||
| blender::Span<InstanceReference> InstancesComponent::references() const | blender::Span<InstanceReference> InstancesComponent::references() const | ||||
| { | { | ||||
| return references_; | return references_; | ||||
| } | } | ||||
| template<typename T> | |||||
| static void copy_data_based_on_mask(Span<T> src, MutableSpan<T> dst, IndexMask mask) | |||||
| { | |||||
| BLI_assert(src.data() != dst.data()); | |||||
| using namespace blender; | |||||
| threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) { | |||||
| for (const int i : range) { | |||||
| dst[i] = src[mask[i]]; | |||||
| } | |||||
| }); | |||||
| } | |||||
| void InstancesComponent::remove_instances(const IndexMask mask) | |||||
| { | |||||
| using namespace blender; | |||||
| if (mask.is_range() && mask.as_range().start() == 0) { | |||||
| /* Deleting from the end of the array can be much faster since no data has to be shifted. */ | |||||
| this->resize(mask.size()); | |||||
| this->remove_unused_references(); | |||||
| return; | |||||
| } | |||||
| Vector<int> new_handles(mask.size()); | |||||
| copy_data_based_on_mask<int>(this->instance_reference_handles(), new_handles, mask); | |||||
| instance_reference_handles_ = std::move(new_handles); | |||||
| Vector<float4x4> new_transforms(mask.size()); | |||||
| copy_data_based_on_mask<float4x4>(this->instance_transforms(), new_transforms, mask); | |||||
| instance_transforms_ = std::move(new_transforms); | |||||
| const bke::CustomDataAttributes &src_attributes = attributes_; | |||||
| bke::CustomDataAttributes dst_attributes; | |||||
| dst_attributes.reallocate(mask.size()); | |||||
| src_attributes.foreach_attribute( | |||||
| [&](const bke::AttributeIDRef &id, const AttributeMetaData &meta_data) { | |||||
| if (!id.should_be_kept()) { | |||||
| return true; | |||||
| } | |||||
| GSpan src = *src_attributes.get_for_read(id); | |||||
| dst_attributes.create(id, meta_data.data_type); | |||||
| fn::GMutableSpan dst = *dst_attributes.get_for_write(id); | |||||
| attribute_math::convert_to_static_type(src.type(), [&](auto dummy) { | |||||
| using T = decltype(dummy); | |||||
| copy_data_based_on_mask<T>(src.typed<T>(), dst.typed<T>(), mask); | |||||
| }); | |||||
| return true; | |||||
| }, | |||||
| ATTR_DOMAIN_INSTANCE); | |||||
| attributes_ = std::move(dst_attributes); | |||||
| this->remove_unused_references(); | |||||
| } | |||||
| void InstancesComponent::remove_unused_references() | void InstancesComponent::remove_unused_references() | ||||
| { | { | ||||
| using namespace blender; | using namespace blender; | ||||
| using namespace blender::bke; | using namespace blender::bke; | ||||
| const int tot_instances = this->instances_amount(); | const int tot_instances = this->instances_amount(); | ||||
| const int tot_references_before = references_.size(); | const int tot_references_before = references_.size(); | ||||
| ▲ Show 20 Lines • Show All 313 Lines • Show Last 20 Lines | |||||