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/intern
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/intern')
-rw-r--r--source/blender/functions/intern/field.cc72
-rw-r--r--source/blender/functions/intern/multi_function_builder.cc21
2 files changed, 91 insertions, 2 deletions
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index fa7dea97b7f..6133658d8e3 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -462,6 +462,29 @@ void evaluate_constant_field(const GField &field, void *r_value)
varrays[0]->get_to_uninitialized(0, r_value);
}
+/**
+ * If the field depends on some input, the same field is returned.
+ * Otherwise the field is evaluated and a new field is created that just computes this constant.
+ *
+ * Making the field constant has two benefits:
+ * - The field-tree becomes a single node, which is more efficient when the field is evaluated many
+ * times.
+ * - Memory of the input fields may be freed.
+ */
+GField make_field_constant_if_possible(GField field)
+{
+ if (field.node().depends_on_input()) {
+ return field;
+ }
+ const CPPType &type = field.cpp_type();
+ BUFFER_FOR_CPP_TYPE_VALUE(type, buffer);
+ evaluate_constant_field(field, buffer);
+ auto constant_fn = std::make_unique<CustomMF_GenericConstant>(type, buffer, true);
+ type.destruct(buffer);
+ auto operation = std::make_shared<FieldOperation>(std::move(constant_fn));
+ return GField{operation, 0};
+}
+
const GVArray *FieldContext::get_varray_for_input(const FieldInput &field_input,
IndexMask mask,
ResourceScope &scope) const
@@ -472,6 +495,55 @@ const GVArray *FieldContext::get_varray_for_input(const FieldInput &field_input,
}
/* --------------------------------------------------------------------
+ * FieldOperation.
+ */
+
+FieldOperation::FieldOperation(std::unique_ptr<const MultiFunction> function,
+ Vector<GField> inputs)
+ : FieldOperation(*function, std::move(inputs))
+{
+ owned_function_ = std::move(function);
+}
+
+static bool any_field_depends_on_input(Span<GField> fields)
+{
+ for (const GField &field : fields) {
+ if (field.node().depends_on_input()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+FieldOperation::FieldOperation(const MultiFunction &function, Vector<GField> inputs)
+ : FieldNode(false, any_field_depends_on_input(inputs)),
+ function_(&function),
+ inputs_(std::move(inputs))
+{
+}
+
+void FieldOperation::foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const
+{
+ for (const GField &field : inputs_) {
+ field.node().foreach_field_input(foreach_fn);
+ }
+}
+
+/* --------------------------------------------------------------------
+ * FieldInput.
+ */
+
+FieldInput::FieldInput(const CPPType &type, std::string debug_name)
+ : FieldNode(true, true), type_(&type), debug_name_(std::move(debug_name))
+{
+}
+
+void FieldInput::foreach_field_input(FunctionRef<void(const FieldInput &)> foreach_fn) const
+{
+ foreach_fn(*this);
+}
+
+/* --------------------------------------------------------------------
* FieldEvaluator.
*/
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 180d1f17a54..f891f162820 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -20,9 +20,18 @@
namespace blender::fn {
-CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const void *value)
- : type_(type), value_(value)
+CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type,
+ const void *value,
+ bool make_value_copy)
+ : type_(type), owns_value_(make_value_copy)
{
+ if (make_value_copy) {
+ void *copied_value = MEM_mallocN_aligned(type.size(), type.alignment(), __func__);
+ type.copy_construct(value, copied_value);
+ value = copied_value;
+ }
+ value_ = value;
+
MFSignatureBuilder signature{"Constant " + type.name()};
std::stringstream ss;
type.print_or_default(value, ss, type.name());
@@ -31,6 +40,14 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const vo
this->set_signature(&signature_);
}
+CustomMF_GenericConstant::~CustomMF_GenericConstant()
+{
+ if (owns_value_) {
+ signature_.param_types[0].data_type().single_type().destruct((void *)value_);
+ MEM_freeN((void *)value_);
+ }
+}
+
void CustomMF_GenericConstant::call(IndexMask mask,
MFParams params,
MFContext UNUSED(context)) const