diff options
author | Jacques Lucke <jacques@blender.org> | 2021-04-20 10:30:53 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-04-20 10:30:53 +0300 |
commit | 8c0f7d17725d1f8700718dab19c368a5ab5fe8d4 (patch) | |
tree | 6194a1759923579489b88076c116ef14640e09d3 /source/blender | |
parent | 5d2ec2bc08275666a85b218167fc4d28ab230595 (diff) |
Geometry Nodes: support geometry nodes modifier on volume objects
Differential Revision: https://developer.blender.org/D11011
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/volume.cc | 74 | ||||
-rw-r--r-- | source/blender/editors/space_spreadsheet/space_spreadsheet.cc | 2 |
3 files changed, 52 insertions, 26 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 160fb93b835..522b4549f57 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1336,7 +1336,7 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) return (mti->modifyGeometrySet != NULL); } if (ob->type == OB_VOLUME) { - return (mti->modifyVolume != NULL); + return (mti->modifyVolume != NULL) || (mti->modifyGeometrySet != NULL); } if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) { diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 7b03839f659..93d5e116131 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -39,6 +39,7 @@ #include "BLI_utildefines.h" #include "BKE_anim_data.h" +#include "BKE_geometry_set.hh" #include "BKE_global.h" #include "BKE_idtype.h" #include "BKE_lib_id.h" @@ -1003,13 +1004,12 @@ static void volume_update_simplify_level(Volume *volume, const Depsgraph *depsgr #endif } -static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph, - struct Scene *scene, - Object *object, - Volume *volume_input) +static void volume_evaluate_modifiers(struct Depsgraph *depsgraph, + struct Scene *scene, + Object *object, + Volume *volume_input, + GeometrySet &geometry_set) { - Volume *volume = volume_input; - /* Modifier evaluation modes. */ const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER); const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime; @@ -1030,25 +1030,22 @@ static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph, continue; } - if (mti->modifyVolume) { - /* Ensure we are not modifying the input. */ - if (volume == volume_input) { - volume = BKE_volume_copy_for_eval(volume, true); + if (mti->modifyGeometrySet) { + mti->modifyGeometrySet(md, &mectx, &geometry_set); + } + else if (mti->modifyVolume) { + VolumeComponent &volume_component = geometry_set.get_component_for_write<VolumeComponent>(); + Volume *volume_old = volume_component.get_for_write(); + if (volume_old == nullptr) { + volume_old = BKE_volume_new_for_eval(volume_input); + volume_component.replace(volume_old); } - - Volume *volume_next = mti->modifyVolume(md, &mectx, volume); - - if (volume_next && volume_next != volume) { - /* If the modifier returned a new volume, release the old one. */ - if (volume != volume_input) { - BKE_id_free(nullptr, volume); - } - volume = volume_next; + Volume *volume_new = mti->modifyVolume(md, &mectx, volume_old); + if (volume_new != volume_old) { + volume_component.replace(volume_new); } } } - - return volume; } void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, Volume *volume) @@ -1072,6 +1069,24 @@ void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, Volume *volume) } } +static Volume *take_volume_ownership_from_geometry_set(GeometrySet &geometry_set) +{ + if (!geometry_set.has<VolumeComponent>()) { + return nullptr; + } + VolumeComponent &volume_component = geometry_set.get_component_for_write<VolumeComponent>(); + Volume *volume = volume_component.release(); + if (volume != nullptr) { + /* Add back, but only as read-only non-owning component. */ + volume_component.replace(volume, GeometryOwnershipType::ReadOnly); + } + else { + /* The component was empty, we can remove it. */ + geometry_set.remove<VolumeComponent>(); + } + return volume; +} + void BKE_volume_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object) { /* Free any evaluated data and restore original data. */ @@ -1079,11 +1094,22 @@ void BKE_volume_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Ob /* Evaluate modifiers. */ Volume *volume = (Volume *)object->data; - Volume *volume_eval = volume_evaluate_modifiers(depsgraph, scene, object, volume); + GeometrySet geometry_set; + VolumeComponent &volume_component = geometry_set.get_component_for_write<VolumeComponent>(); + volume_component.replace(volume, GeometryOwnershipType::ReadOnly); + volume_evaluate_modifiers(depsgraph, scene, object, volume, geometry_set); + + Volume *volume_eval = take_volume_ownership_from_geometry_set(geometry_set); + + /* If the geometry set did not contain a volume, we still create an empty one. */ + if (volume_eval == nullptr) { + volume_eval = BKE_volume_new_for_eval(volume); + } /* Assign evaluated object. */ - const bool is_owned = (volume != volume_eval); - BKE_object_eval_assign_data(object, &volume_eval->id, is_owned); + const bool eval_is_owned = (volume != volume_eval); + BKE_object_eval_assign_data(object, &volume_eval->id, eval_is_owned); + object->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set)); } void BKE_volume_grids_backup_restore(Volume *volume, VolumeGridVector *grids, const char *filepath) diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index 190f50ed443..26f89a0700e 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -256,7 +256,7 @@ static std::unique_ptr<DataSource> get_data_source(const bContext *C) return {}; } Object *object_orig = (Object *)used_id; - if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD)) { + if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME)) { return {}; } Object *object_eval = DEG_get_evaluated_object(depsgraph, object_orig); |