Functions: add method to iterate over all inputs of a field

This is part of D16858. Iterating over all field inputs allows us to extract
all anonymous attributes used by a field relatively easily which is necessary
for D16858.

This could potentially be used for better field tooltips for nested fields,
but that needs further investigation.
This commit is contained in:
Jacques Lucke 2023-01-03 12:37:18 +01:00
parent 0f8487f640
commit 30753f7692
18 changed files with 123 additions and 3 deletions

View File

@ -84,6 +84,12 @@ class FieldNode {
virtual uint64_t hash() const;
virtual bool is_equal_to(const FieldNode &other) const;
/**
* Calls the callback for every field input that the current field depends on. This is recursive,
* so if a field input depends on other field inputs, those are taken into account as well.
*/
virtual void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const;
};
/**

View File

@ -579,6 +579,18 @@ bool IndexFieldInput::is_equal_to(const fn::FieldNode &other) const
/* Avoid generating the destructor in every translation unit. */
FieldNode::~FieldNode() = default;
void FieldNode::for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
if (field_inputs_) {
for (const FieldInput &field_input : field_inputs_->deduplicated_nodes) {
fn(field_input);
if (&field_input != this) {
field_input.for_each_field_input_recursive(fn);
}
}
}
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -440,6 +440,12 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput {
return GVArray::ForGArray(std::move(main_buffer));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
weight_field_.node().for_each_field_input_recursive(fn);
value_field_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
return get_default_hash_3(iterations_, weight_field_, value_field_);

View File

@ -77,6 +77,12 @@ class EndpointFieldInput final : public bke::CurvesFieldInput {
return VArray<bool>::ForContainer(std::move(selection));
};
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
start_size_.node().for_each_field_input_recursive(fn);
end_size_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
return get_default_hash_2(start_size_, end_size_);

View File

@ -101,6 +101,13 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput {
return VArray<int>::ForContainer(std::move(point_of_curve));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
curve_index_.node().for_each_field_input_recursive(fn);
sort_index_.node().for_each_field_input_recursive(fn);
sort_weight_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
return 26978695677882;

View File

@ -92,6 +92,12 @@ class PathToEdgeSelectionFieldInput final : public bke::MeshFieldInput {
VArray<bool>::ForContainer(std::move(selection)), ATTR_DOMAIN_EDGE, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
start_vertices_.node().for_each_field_input_recursive(fn);
next_vertex_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
return get_default_hash_2(start_vertices_, next_vertex_);

View File

@ -71,6 +71,11 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput {
VArray<float3>::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
relative_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
return get_default_hash_2(relative_, left_);

View File

@ -76,6 +76,11 @@ class PlanarFieldInput final : public bke::MeshFieldInput {
VArray<bool>::ForFunc(polys.size(), planar_fn), ATTR_DOMAIN_FACE, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
threshold_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
/* Some random constant hash. */

View File

@ -129,6 +129,12 @@ class ShortestEdgePathsNextVertFieldInput final : public bke::MeshFieldInput {
VArray<int>::ForContainer(std::move(next_index)), ATTR_DOMAIN_POINT, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
end_selection_.node().for_each_field_input_recursive(fn);
cost_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const override
{
/* Some random constant hash. */

View File

@ -112,6 +112,11 @@ class InterpolateDomain final : public bke::GeometryFieldInput {
GVArray::ForGArray(std::move(values)), src_domain_, context.domain());
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
src_field_.node().for_each_field_input_recursive(fn);
}
std::optional<eAttrDomain> preferred_domain(
const GeometryComponent & /*component*/) const override
{

View File

@ -24,11 +24,11 @@ static void node_declare(NodeDeclarationBuilder &b)
class BoundaryFieldInput final : public bke::MeshFieldInput {
private:
const Field<int> face_set;
const Field<int> face_set_;
public:
BoundaryFieldInput(const Field<int> face_set)
: bke::MeshFieldInput(CPPType::get<bool>(), "Boundary Field"), face_set(face_set)
: bke::MeshFieldInput(CPPType::get<bool>(), "Boundary Field"), face_set_(face_set)
{
category_ = Category::Generated;
}
@ -39,7 +39,7 @@ class BoundaryFieldInput final : public bke::MeshFieldInput {
{
const bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator face_evaluator{face_context, mesh.totpoly};
face_evaluator.add(face_set);
face_evaluator.add(face_set_);
face_evaluator.evaluate();
const VArray<int> face_set = face_evaluator.get_evaluated<int>(0);
@ -66,6 +66,11 @@ class BoundaryFieldInput final : public bke::MeshFieldInput {
VArray<bool>::ForContainer(std::move(boundary)), ATTR_DOMAIN_EDGE, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
face_set_.node().for_each_field_input_recursive(fn);
}
std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
{
return ATTR_DOMAIN_EDGE;

View File

@ -105,6 +105,13 @@ class CornersOfFaceInput final : public bke::MeshFieldInput {
return VArray<int>::ForContainer(std::move(corner_of_face));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
face_index_.node().for_each_field_input_recursive(fn);
sort_index_.node().for_each_field_input_recursive(fn);
sort_weight_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const final
{
return 6927982716657;

View File

@ -126,6 +126,13 @@ class CornersOfVertInput final : public bke::MeshFieldInput {
return VArray<int>::ForContainer(std::move(corner_of_vertex));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
vert_index_.node().for_each_field_input_recursive(fn);
sort_index_.node().for_each_field_input_recursive(fn);
sort_weight_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const final
{
return 3541871368173645;

View File

@ -126,6 +126,13 @@ class EdgesOfVertInput final : public bke::MeshFieldInput {
return VArray<int>::ForContainer(std::move(edge_of_vertex));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
vert_index_.node().for_each_field_input_recursive(fn);
sort_index_.node().for_each_field_input_recursive(fn);
sort_weight_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const final
{
return 98762349875636;

View File

@ -73,6 +73,12 @@ class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput {
return VArray<int>::ForContainer(std::move(offset_corners));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
corner_index_.node().for_each_field_input_recursive(fn);
offset_.node().for_each_field_input_recursive(fn);
}
uint64_t hash() const final
{
return get_default_hash(offset_);

View File

@ -89,6 +89,12 @@ class ControlPointNeighborFieldInput final : public bke::CurvesFieldInput {
return VArray<int>::ForContainer(std::move(output));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
index_.node().for_each_field_input_recursive(fn);
offset_.node().for_each_field_input_recursive(fn);
}
};
class OffsetValidFieldInput final : public bke::CurvesFieldInput {
@ -138,6 +144,12 @@ class OffsetValidFieldInput final : public bke::CurvesFieldInput {
};
return VArray<bool>::ForContainer(std::move(output));
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
index_.node().for_each_field_input_recursive(fn);
offset_.node().for_each_field_input_recursive(fn);
}
};
static void node_geo_exec(GeoNodeExecParams params)

View File

@ -119,6 +119,12 @@ class PackIslandsFieldInput final : public bke::MeshFieldInput {
return construct_uv_gvarray(mesh, selection_field, uv_field, rotate, margin, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
selection_field.node().for_each_field_input_recursive(fn);
uv_field.node().for_each_field_input_recursive(fn);
}
std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
{
return ATTR_DOMAIN_CORNER;

View File

@ -161,6 +161,12 @@ class UnwrapFieldInput final : public bke::MeshFieldInput {
return construct_uv_gvarray(mesh, selection, seam, fill_holes, margin, method, domain);
}
void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const
{
selection.node().for_each_field_input_recursive(fn);
seam.node().for_each_field_input_recursive(fn);
}
std::optional<eAttrDomain> preferred_domain(const Mesh & /*mesh*/) const override
{
return ATTR_DOMAIN_CORNER;