diff options
author | Jacques Lucke <jacques@blender.org> | 2021-01-21 12:32:42 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-01-21 12:32:42 +0300 |
commit | 793547e7d1401ad545e0450b80c7bafd521c60e1 (patch) | |
tree | 74ebdf40005711eb545fd1889bcf8226dd5bcafd /source/blender/blenkernel/intern/geometry_set.cc | |
parent | 985bc08688b7fb58a910171c63a1417580cffece (diff) |
Geometry Nodes: initial support for volumes
For the most part, this just adds boilerplate code for volume support in geometry nodes:
* Add `VolumeComponent` next to `MeshComponent`, etc.
* Support `VolumeComponent` in depsgraph object iterator.
Furthermore, I added initial volume support in a few nodes:
* The Object Info node outputs an object instance when the input is a volume object
(that will be the same for mesh objects soonish, to avoid copies).
* Support transforming a `VolumeComponent` in the Transform node.
* Support the `VolumeComponent` in Join Geometry nodes, but only when just one of the
inputs has a volume component for now.
Right now, there is no way to create a `VolumeComponent`, because the Object Info node
outputs an object instance. The `VolumeComponent` will be necessary for upcoming nodes,
which will generate volumes on the fly.
Viewport selection does not work correctly with `VolumeComponent`s currently. I don't
know why that is. That can be figured out a bit later, once we can actually create
new volumes in geometry nodes.
Ref T84604.
Differential Revision: https://developer.blender.org/D10147
Diffstat (limited to 'source/blender/blenkernel/intern/geometry_set.cc')
-rw-r--r-- | source/blender/blenkernel/intern/geometry_set.cc | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 81958b81213..7a3239babd4 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -19,6 +19,7 @@ #include "BKE_mesh.h" #include "BKE_mesh_wrapper.h" #include "BKE_pointcloud.h" +#include "BKE_volume.h" #include "DNA_object_types.h" @@ -51,6 +52,8 @@ GeometryComponent *GeometryComponent::create(GeometryComponentType component_typ return new PointCloudComponent(); case GeometryComponentType::Instances: return new InstancesComponent(); + case GeometryComponentType::Volume: + return new VolumeComponent(); } BLI_assert(false); return nullptr; @@ -201,6 +204,13 @@ const PointCloud *GeometrySet::get_pointcloud_for_read() const 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. */ bool GeometrySet::has_pointcloud() const { @@ -215,6 +225,13 @@ bool GeometrySet::has_instances() const 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. */ GeometrySet GeometrySet::create_with_mesh(Mesh *mesh, GeometryOwnershipType ownership) { @@ -262,6 +279,13 @@ PointCloud *GeometrySet::get_pointcloud_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(); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -567,6 +591,85 @@ bool InstancesComponent::is_empty() const /** \} */ /* -------------------------------------------------------------------- */ +/** \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 * \{ */ |