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:
authorJacques Lucke <jacques@blender.org>2021-09-11 14:05:20 +0300
committerJacques Lucke <jacques@blender.org>2021-09-11 14:05:20 +0300
commit4e78b89e487e9b9707d583c6b2578ad122c59d5e (patch)
tree620c9d0e0114488328cc55187dadfdb4f8a05754 /source/blender/functions/FN_field.hh
parent166c8be7ac018c461514453b9947a23b7ac2ef26 (diff)
Geometry Nodes: add field support for socket inspection
Since fields were committed to master, socket inspection did not work correctly for all socket types anymore. Now the same functionality as before is back. Furthermore, fields that depend on some input will now show the inputs in the socket inspection. I added support for evaluating constant fields more immediately. This has the benefit that the same constant field is not evaluated more than once. It also helps with making the field independent of the multi-functions that it uses. We might still want to change the ownership handling for the multi-functions of nodes a bit, but that can be done separately. Differential Revision: https://developer.blender.org/D12444
Diffstat (limited to 'source/blender/functions/FN_field.hh')
-rw-r--r--source/blender/functions/FN_field.hh59
1 files changed, 44 insertions, 15 deletions
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index 79a6faf499b..976d260d91b 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -46,6 +46,7 @@
* they share common sub-fields and a common context.
*/
+#include "BLI_function_ref.hh"
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
@@ -57,15 +58,27 @@
namespace blender::fn {
+class FieldInput;
+
/**
* A node in a field-tree. It has at least one output that can be referenced by fields.
*/
class FieldNode {
private:
bool is_input_;
+ /**
+ * 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.
+ */
+ bool depends_on_input_;
public:
- FieldNode(bool is_input) : is_input_(is_input)
+ FieldNode(bool is_input, bool depends_on_input)
+ : is_input_(is_input), depends_on_input_(depends_on_input)
{
}
@@ -83,6 +96,17 @@ class FieldNode {
return !is_input_;
}
+ bool depends_on_input() const
+ {
+ return depends_on_input_;
+ }
+
+ /**
+ * 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;
+
virtual uint64_t hash() const
{
return get_default_hash(this);
@@ -93,6 +117,11 @@ class FieldNode {
return a.is_equal_to(b);
}
+ friend bool operator!=(const FieldNode &a, const FieldNode &b)
+ {
+ return !(a == b);
+ }
+
virtual bool is_equal_to(const FieldNode &other) const
{
return this == &other;
@@ -211,16 +240,8 @@ class FieldOperation : public FieldNode {
blender::Vector<GField> inputs_;
public:
- FieldOperation(std::unique_ptr<const MultiFunction> function, Vector<GField> inputs = {})
- : FieldNode(false), owned_function_(std::move(function)), inputs_(std::move(inputs))
- {
- function_ = owned_function_.get();
- }
-
- FieldOperation(const MultiFunction &function, Vector<GField> inputs = {})
- : FieldNode(false), function_(&function), inputs_(std::move(inputs))
- {
- }
+ FieldOperation(std::unique_ptr<const MultiFunction> function, Vector<GField> inputs = {});
+ FieldOperation(const MultiFunction &function, Vector<GField> inputs = {});
Span<GField> inputs() const
{
@@ -247,6 +268,8 @@ class FieldOperation : public FieldNode {
BLI_assert_unreachable();
return CPPType::get<float>();
}
+
+ void foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const override;
};
class FieldContext;
@@ -260,10 +283,7 @@ class FieldInput : public FieldNode {
std::string debug_name_;
public:
- FieldInput(const CPPType &type, std::string debug_name = "")
- : FieldNode(true), type_(&type), debug_name_(std::move(debug_name))
- {
- }
+ FieldInput(const CPPType &type, std::string debug_name = "");
/**
* Get the value of this specific input based on the given context. The returned virtual array,
@@ -273,6 +293,11 @@ class FieldInput : public FieldNode {
IndexMask mask,
ResourceScope &scope) const = 0;
+ virtual std::string socket_inspection_name() const
+ {
+ return debug_name_;
+ }
+
blender::StringRef debug_name() const
{
return debug_name_;
@@ -289,6 +314,8 @@ class FieldInput : public FieldNode {
UNUSED_VARS_NDEBUG(output_index);
return *type_;
}
+
+ void foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const override;
};
/**
@@ -453,4 +480,6 @@ template<typename T> Field<T> make_constant_field(T value)
return Field<T>{GField{std::move(operation), 0}};
}
+GField make_field_constant_if_possible(GField field);
+
} // namespace blender::fn