Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/geometry_set.cc
| Show All 13 Lines | |||||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
| */ | */ | ||||
| #include "BKE_geometry_set.hh" | #include "BKE_geometry_set.hh" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_mesh_wrapper.h" | #include "BKE_mesh_wrapper.h" | ||||
| #include "BKE_pointcloud.h" | #include "BKE_pointcloud.h" | ||||
| #include "BKE_volume.h" | |||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| using blender::float3; | using blender::float3; | ||||
| using blender::float4x4; | using blender::float4x4; | ||||
| using blender::MutableSpan; | using blender::MutableSpan; | ||||
| Show All 17 Lines | |||||
| { | { | ||||
| switch (component_type) { | switch (component_type) { | ||||
| case GeometryComponentType::Mesh: | case GeometryComponentType::Mesh: | ||||
| return new MeshComponent(); | return new MeshComponent(); | ||||
| case GeometryComponentType::PointCloud: | case GeometryComponentType::PointCloud: | ||||
| return new PointCloudComponent(); | return new PointCloudComponent(); | ||||
| case GeometryComponentType::Instances: | case GeometryComponentType::Instances: | ||||
| return new InstancesComponent(); | return new InstancesComponent(); | ||||
| case GeometryComponentType::Volume: | |||||
| return new VolumeComponent(); | |||||
| } | } | ||||
| BLI_assert(false); | BLI_assert(false); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| void GeometryComponent::user_add() const | void GeometryComponent::user_add() const | ||||
| { | { | ||||
| users_.fetch_add(1); | users_.fetch_add(1); | ||||
| ▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | |||||
| /* Returns a read-only point cloud of null. */ | /* Returns a read-only point cloud of null. */ | ||||
| const PointCloud *GeometrySet::get_pointcloud_for_read() const | const PointCloud *GeometrySet::get_pointcloud_for_read() const | ||||
| { | { | ||||
| const PointCloudComponent *component = this->get_component_for_read<PointCloudComponent>(); | const PointCloudComponent *component = this->get_component_for_read<PointCloudComponent>(); | ||||
| return (component == nullptr) ? nullptr : component->get_for_read(); | return (component == nullptr) ? nullptr : component->get_for_read(); | ||||
| } | } | ||||
| /* Returns a read-only volume or null. */ | |||||
| const Volume *GeometrySet::get_volume_for_read() const | |||||
| { | |||||
| const VolumeComponent *component = this->get_component_for_read<VolumeComponent>(); | |||||
| return (component == nullptr) ? nullptr : component->get_for_read(); | |||||
| } | |||||
| /* Returns true when the geometry set has a point cloud component that has a point cloud. */ | /* Returns true when the geometry set has a point cloud component that has a point cloud. */ | ||||
| bool GeometrySet::has_pointcloud() const | bool GeometrySet::has_pointcloud() const | ||||
| { | { | ||||
| const PointCloudComponent *component = this->get_component_for_read<PointCloudComponent>(); | const PointCloudComponent *component = this->get_component_for_read<PointCloudComponent>(); | ||||
| return component != nullptr && component->has_pointcloud(); | return component != nullptr && component->has_pointcloud(); | ||||
| } | } | ||||
| /* Returns true when the geometry set has an instances component that has at least one instance. */ | /* Returns true when the geometry set has an instances component that has at least one instance. */ | ||||
| bool GeometrySet::has_instances() const | bool GeometrySet::has_instances() const | ||||
| { | { | ||||
| const InstancesComponent *component = this->get_component_for_read<InstancesComponent>(); | const InstancesComponent *component = this->get_component_for_read<InstancesComponent>(); | ||||
| return component != nullptr && component->instances_amount() >= 1; | return component != nullptr && component->instances_amount() >= 1; | ||||
| } | } | ||||
| /* Returns true when the geometry set has a volume component that has a volume. */ | |||||
| bool GeometrySet::has_volume() const | |||||
| { | |||||
| const VolumeComponent *component = this->get_component_for_read<VolumeComponent>(); | |||||
| return component != nullptr && component->has_volume(); | |||||
| } | |||||
| /* Create a new geometry set that only contains the given mesh. */ | /* Create a new geometry set that only contains the given mesh. */ | ||||
| GeometrySet GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership) | GeometrySet GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership) | ||||
| { | { | ||||
| GeometrySet geometry_set; | GeometrySet geometry_set; | ||||
| MeshComponent &component = geometry_set.get_component_for_write<MeshComponent>(); | MeshComponent &component = geometry_set.get_component_for_write<MeshComponent>(); | ||||
| component.replace(mesh, ownership); | component.replace(mesh, ownership); | ||||
| return geometry_set; | return geometry_set; | ||||
| } | } | ||||
| Show All 31 Lines | |||||
| /* Returns a mutable point cloud or null. No ownership is transferred. */ | /* Returns a mutable point cloud or null. No ownership is transferred. */ | ||||
| PointCloud *GeometrySet::get_pointcloud_for_write() | PointCloud *GeometrySet::get_pointcloud_for_write() | ||||
| { | { | ||||
| PointCloudComponent &component = this->get_component_for_write<PointCloudComponent>(); | PointCloudComponent &component = this->get_component_for_write<PointCloudComponent>(); | ||||
| return component.get_for_write(); | return component.get_for_write(); | ||||
| } | } | ||||
| /* Returns a mutable volume or null. No ownership is transferred. */ | |||||
| Volume *GeometrySet::get_volume_for_write() | |||||
| { | |||||
| VolumeComponent &component = this->get_component_for_write<VolumeComponent>(); | |||||
| return component.get_for_write(); | |||||
| } | |||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Mesh Component | /** \name Mesh Component | ||||
| * \{ */ | * \{ */ | ||||
| MeshComponent::MeshComponent() : GeometryComponent(GeometryComponentType::Mesh) | MeshComponent::MeshComponent() : GeometryComponent(GeometryComponentType::Mesh) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 266 Lines • ▼ Show 20 Lines | |||||
| bool InstancesComponent::is_empty() const | bool InstancesComponent::is_empty() const | ||||
| { | { | ||||
| return transforms_.size() == 0; | return transforms_.size() == 0; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Volume Component | |||||
| * \{ */ | |||||
| VolumeComponent::VolumeComponent() : GeometryComponent(GeometryComponentType::Volume) | |||||
| { | |||||
| } | |||||
| VolumeComponent::~VolumeComponent() | |||||
| { | |||||
| this->clear(); | |||||
| } | |||||
| GeometryComponent *VolumeComponent::copy() const | |||||
| { | |||||
| VolumeComponent *new_component = new VolumeComponent(); | |||||
| if (volume_ != nullptr) { | |||||
| new_component->volume_ = BKE_volume_copy_for_eval(volume_, false); | |||||
| new_component->ownership_ = GeometryOwnershipType::Owned; | |||||
| } | |||||
| return new_component; | |||||
| } | |||||
| void VolumeComponent::clear() | |||||
| { | |||||
| BLI_assert(this->is_mutable()); | |||||
| if (volume_ != nullptr) { | |||||
| if (ownership_ == GeometryOwnershipType::Owned) { | |||||
| BKE_id_free(nullptr, volume_); | |||||
| } | |||||
| volume_ = nullptr; | |||||
| } | |||||
| } | |||||
| bool VolumeComponent::has_volume() const | |||||
| { | |||||
| return volume_ != nullptr; | |||||
| } | |||||
| /* Clear the component and replace it with the new volume. */ | |||||
| void VolumeComponent::replace(Volume *volume, GeometryOwnershipType ownership) | |||||
| { | |||||
| BLI_assert(this->is_mutable()); | |||||
| this->clear(); | |||||
| volume_ = volume; | |||||
| ownership_ = ownership; | |||||
| } | |||||
| /* Return the volume and clear the component. The caller takes over responsibility for freeing the | |||||
| * volume (if the component was responsible before). */ | |||||
| Volume *VolumeComponent::release() | |||||
| { | |||||
| BLI_assert(this->is_mutable()); | |||||
| Volume *volume = volume_; | |||||
| volume_ = nullptr; | |||||
| return volume; | |||||
| } | |||||
| /* Get the volume from this component. This method can be used by multiple threads at the same | |||||
| * time. Therefore, the returned volume should not be modified. No ownership is transferred. */ | |||||
| const Volume *VolumeComponent::get_for_read() const | |||||
| { | |||||
| return volume_; | |||||
| } | |||||
| /* Get the volume from this component. This method can only be used when the component is mutable, | |||||
| * i.e. it is not shared. The returned volume can be modified. No ownership is transferred. */ | |||||
| Volume *VolumeComponent::get_for_write() | |||||
| { | |||||
| BLI_assert(this->is_mutable()); | |||||
| if (ownership_ == GeometryOwnershipType::ReadOnly) { | |||||
| volume_ = BKE_volume_copy_for_eval(volume_, false); | |||||
| ownership_ = GeometryOwnershipType::Owned; | |||||
| } | |||||
| return volume_; | |||||
| } | |||||
| /** \} */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name C API | /** \name C API | ||||
| * \{ */ | * \{ */ | ||||
| void BKE_geometry_set_free(GeometrySet *geometry_set) | void BKE_geometry_set_free(GeometrySet *geometry_set) | ||||
| { | { | ||||
| delete geometry_set; | delete geometry_set; | ||||
| } | } | ||||
| Show All 22 Lines | |||||