Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/functions/FN_field.hh')
-rw-r--r--source/blender/functions/FN_field.hh49
1 files changed, 31 insertions, 18 deletions
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index d82f685e7ea..289ced8929f 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -49,6 +49,7 @@
#include "BLI_function_ref.hh"
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
+#include "BLI_vector_set.hh"
#include "FN_generic_virtual_array.hh"
#include "FN_multi_function_builder.hh"
@@ -59,6 +60,7 @@
namespace blender::fn {
class FieldInput;
+class FieldInputs;
/**
* A node in a field-tree. It has at least one output that can be referenced by fields.
@@ -66,18 +68,18 @@ class FieldInput;
class FieldNode {
private:
bool is_input_;
+
+ protected:
/**
- * True when this node is a #FieldInput or (potentially indirectly) depends on one. This could
- * always be derived again later by traversing the field-tree, but keeping track of it while the
- * field is built is cheaper.
- *
- * If this is false, the field is constant. Note that even when this is true, the field may be
- * constant when all inputs are constant.
+ * Keeps track of the inputs that this node depends on. This avoids recomputing it every time the
+ * data is required. It is a shared pointer, because very often multiple nodes depend on the same
+ * inputs.
+ * Might contain null.
*/
- bool depends_on_input_;
+ std::shared_ptr<const FieldInputs> field_inputs_;
public:
- FieldNode(bool is_input, bool depends_on_input);
+ FieldNode(bool is_input);
virtual ~FieldNode() = default;
@@ -87,11 +89,7 @@ class FieldNode {
bool is_operation() const;
bool depends_on_input() const;
- /**
- * Invoke callback for every field input. It might be called multiple times for the same input.
- * The caller is responsible for deduplication if required.
- */
- virtual void foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const = 0;
+ const std::shared_ptr<const FieldInputs> &field_inputs() const;
virtual uint64_t hash() const;
virtual bool is_equal_to(const FieldNode &other) const;
@@ -231,7 +229,6 @@ class FieldOperation : public FieldNode {
const MultiFunction &multi_function() const;
const CPPType &output_cpp_type(int output_index) const override;
- void foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const override;
};
class FieldContext;
@@ -271,7 +268,19 @@ class FieldInput : public FieldNode {
Category category() const;
const CPPType &output_cpp_type(int output_index) const override;
- void foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const override;
+};
+
+/**
+ * Keeps track of the inputs of a field.
+ */
+struct FieldInputs {
+ /** All #FieldInput nodes that a field (possibly indirectly) depends on. */
+ VectorSet<const FieldInput *> nodes;
+ /**
+ * Same as above but the inputs are deduplicated. For example, when there are two separate index
+ * input nodes, only one will show up in this list.
+ */
+ VectorSet<std::reference_wrapper<const FieldInput>> deduplicated_nodes;
};
/**
@@ -529,8 +538,7 @@ template<typename T> struct ValueOrField {
/** \name #FieldNode Inline Methods
* \{ */
-inline FieldNode::FieldNode(bool is_input, bool depends_on_input)
- : is_input_(is_input), depends_on_input_(depends_on_input)
+inline FieldNode::FieldNode(bool is_input) : is_input_(is_input)
{
}
@@ -546,7 +554,12 @@ inline bool FieldNode::is_operation() const
inline bool FieldNode::depends_on_input() const
{
- return depends_on_input_;
+ return field_inputs_ && !field_inputs_->nodes.is_empty();
+}
+
+inline const std::shared_ptr<const FieldInputs> &FieldNode::field_inputs() const
+{
+ return field_inputs_;
}
inline uint64_t FieldNode::hash() const