WIP: Volume grid attribute support in geometry nodes #110044

Closed
Lukas Tönne wants to merge 130 commits from LukasTonne/blender:geometry-nodes-flip into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 57 additions and 16 deletions
Showing only changes of commit ae41cf02a8 - Show all commits

View File

@ -168,6 +168,14 @@ class GeometryFieldInput : public fn::FieldInput {
ResourceScope &scope) const override;
virtual GVArray get_varray_for_context(const GeometryFieldContext &context,
const IndexMask &mask) const = 0;
virtual fn::VolumeGrid get_volume_grid_for_context(const fn::FieldContext &context,
const fn::VolumeMask &mask,
ResourceScope &scope) const override;
virtual fn::VolumeGrid get_volume_grid_for_context(const GeometryFieldContext & /*context*/,
const fn::VolumeMask & /*mask*/) const
{
return {};
}
virtual std::optional<eAttrDomain> preferred_domain(const GeometryComponent &component) const;
};
@ -218,12 +226,17 @@ class InstancesFieldInput : public fn::FieldInput {
class VolumeFieldInput : public fn::FieldInput {
public:
using fn::FieldInput::FieldInput;
GVArray get_varray_for_context(const fn::FieldContext &context,
const IndexMask &mask,
ResourceScope &scope) const override;
virtual GVArray get_varray_for_context(const VolumeGridVector &grids,
eAttrDomain domain,
const IndexMask &mask) const = 0;
GVArray get_varray_for_context(const fn::FieldContext & /*context*/,
const IndexMask & /*mask*/,
ResourceScope & /*scope*/) const override
{
return {};
}
virtual fn::VolumeGrid get_volume_grid_for_context(const fn::FieldContext &context,
const fn::VolumeMask &mask,
ResourceScope &scope) const override;
virtual fn::VolumeGrid get_volume_grid_for_context(const VolumeGridVector &grids,
const fn::VolumeMask &mask) const = 0;
};
class AttributeFieldInput : public GeometryFieldInput {

View File

@ -193,6 +193,23 @@ GVArray GeometryFieldInput::get_varray_for_context(const fn::FieldContext &conte
return {};
}
fn::VolumeGrid GeometryFieldInput::get_volume_grid_for_context(const fn::FieldContext &context,
const fn::VolumeMask &mask,
ResourceScope & /*scope*/) const
{
if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>(
&context))
{
return this->get_volume_grid_for_context(*geometry_context, mask);
}
if (const VolumeFieldContext *volume_context = dynamic_cast<const VolumeFieldContext *>(
&context))
{
return this->get_volume_grid_for_context(GeometryFieldContext{volume_context->grids()}, mask);
}
return {};
}
std::optional<eAttrDomain> GeometryFieldInput::preferred_domain(
const GeometryComponent & /*component*/) const
{
@ -284,21 +301,21 @@ GVArray InstancesFieldInput::get_varray_for_context(const fn::FieldContext &cont
return {};
}
GVArray VolumeFieldInput::get_varray_for_context(const fn::FieldContext &context,
const IndexMask &mask,
ResourceScope & /*scope*/) const
fn::VolumeGrid VolumeFieldInput::get_volume_grid_for_context(const fn::FieldContext &context,
const fn::VolumeMask &mask,
ResourceScope & /*scope*/) const
{
if (const GeometryFieldContext *geometry_context = dynamic_cast<const GeometryFieldContext *>(
&context))
{
if (const VolumeGridVector *grids = geometry_context->grids()) {
return this->get_varray_for_context(*grids, geometry_context->domain(), mask);
return this->get_volume_grid_for_context(*grids, mask);
}
}
if (const VolumeFieldContext *volume_context = dynamic_cast<const VolumeFieldContext *>(
&context))
{
return this->get_varray_for_context(volume_context->grids(), volume_context->domain(), mask);
return this->get_volume_grid_for_context(volume_context->grids(), mask);
}
return {};
}

View File

@ -283,6 +283,16 @@ class FieldInput : public FieldNode {
virtual GVArray get_varray_for_context(const FieldContext &context,
const IndexMask &mask,
ResourceScope &scope) const = 0;
/**
* Get the value of this specific input based on the given context. The returned grid should live
* at least as long as the passed in #scope. May return null.
*/
virtual VolumeGrid get_volume_grid_for_context(const FieldContext & /*context*/,
const VolumeMask & /*mask*/,
ResourceScope & /*scope*/) const
{
return {};
}
virtual std::string socket_inspection_name() const;
blender::StringRef debug_name() const;

View File

@ -748,12 +748,13 @@ GVArray FieldContext::get_varray_for_input(const FieldInput &field_input,
return field_input.get_varray_for_context(*this, mask, scope);
}
VolumeGrid FieldContext::get_volume_grid_for_input(const FieldInput & /*field_input*/,
const VolumeMask & /*mask*/,
ResourceScope & /*scope*/) const
VolumeGrid FieldContext::get_volume_grid_for_input(const FieldInput &field_input,
const VolumeMask &mask,
ResourceScope &scope) const
{
/* Implemented only by volume context. */
return {};
/* By default ask the field input to create the varray. Another field context might overwrite
* the context here. */
return field_input.get_volume_grid_for_context(*this, mask, scope);
}
IndexFieldInput::IndexFieldInput() : FieldInput(CPPType::get<int>(), "Index")