diff options
author | Jacques Lucke <jacques@blender.org> | 2020-12-15 14:42:10 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-12-15 14:42:10 +0300 |
commit | 0d58eabee620cc534fab075764a83f5a328100c1 (patch) | |
tree | 924856455cad7fa770e88f6f5c3ab118152c8363 /source/blender/blenkernel/intern/pointcloud.cc | |
parent | d8db5cb6003c84594f5c2f6a85a02f60bafe72c1 (diff) |
Geometry Nodes: support evaluating mesh object to geometry set
This implements the design proposed in T83357.
The goal is to allow the geometry nodes modifier on mesh objects to
output instances and potentially other geometry types. Both problems
are tackled by allowing mesh objects to evaluate to a geometry set,
instead of just a single mesh id data block. The geometry set can
contain a mesh but also other data like instances and a point cloud.
I can't say that I'm sure that this commit won't introduce bugs. Mainly
the temporary object creation during rendering seems a bit brittle.
BUT, we can be reasonably sure that this commit will not introduce
regressions (at least not ones, that are hard to fix). This is because
the code has been written in a way that minimizes changes for existing
functionality.
Given that we intend to hide the point cloud object for the next release,
we won't even have to worry about temporary object creation for now.
An important part of the technical design is to make sure that
`ObjectRuntime->data_eval` contains the same data before and after this
patch. This helps to make sure, that existing code paths are impacted as
little as possible.
Instead of fully replacing `data_eval`, there is `geometry_set_eval`,
which contains all the geometry components an object evaluated to
(including the data referenced by `data_eval`).
For now, not much code has to be aware of `geometry_set_eval`. Mainly
the depsgraph object iterator and the instances system have to know
about it.
Reviewers: brecht
Differential Revision: https://developer.blender.org/D9851
Diffstat (limited to 'source/blender/blenkernel/intern/pointcloud.cc')
-rw-r--r-- | source/blender/blenkernel/intern/pointcloud.cc | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index b4a9ad73048..7bd14e80333 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -371,6 +371,25 @@ static void pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph, } } +static PointCloud *take_pointcloud_ownership_from_geometry_set(GeometrySet &geometry_set) +{ + if (!geometry_set.has<PointCloudComponent>()) { + return nullptr; + } + PointCloudComponent &pointcloud_component = + geometry_set.get_component_for_write<PointCloudComponent>(); + PointCloud *pointcloud = pointcloud_component.release(); + if (pointcloud != nullptr) { + /* Add back, but as read-only non-owning component. */ + pointcloud_component.replace(pointcloud, GeometryOwnershipType::ReadOnly); + } + else { + /* The component was empty, we can also remove it. */ + geometry_set.remove<PointCloudComponent>(); + } + return pointcloud; +} + void BKE_pointcloud_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object) { /* Free any evaluated data and restore original data. */ @@ -382,10 +401,17 @@ void BKE_pointcloud_data_update(struct Depsgraph *depsgraph, struct Scene *scene GeometryOwnershipType::ReadOnly); pointcloud_evaluate_modifiers(depsgraph, scene, object, geometry_set); + PointCloud *pointcloud_eval = take_pointcloud_ownership_from_geometry_set(geometry_set); + + /* If the geometry set did not contain a point cloud, we still create an empty one. */ + if (pointcloud_eval == nullptr) { + pointcloud_eval = BKE_pointcloud_new_nomain(0); + } + /* Assign evaluated object. */ - PointCloud *dummy_pointcloud = BKE_pointcloud_new_nomain(0); - BKE_object_eval_assign_data(object, &dummy_pointcloud->id, true); - object->runtime.geometry_set_eval = new GeometrySet(geometry_set); + const bool eval_is_owned = pointcloud_eval != pointcloud; + BKE_object_eval_assign_data(object, &pointcloud_eval->id, eval_is_owned); + object->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set)); } /* Draw Cache */ |