Geometry Nodes: support geometry nodes modifier on volume objects
Differential Revision: https://developer.blender.org/D11011
This commit is contained in:
parent
5d2ec2bc08
commit
8c0f7d1772
Notes:
blender-bot
2023-02-14 00:10:08 +01:00
Referenced by issue #87422, Volume object "geometry node" modifier
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue