[Bf-blender-cvs] [f487dbae97f] temp-geometry-nodes-fields: use GFieldRef where appropriate
Jacques Lucke
noreply at git.blender.org
Fri Sep 3 13:29:32 CEST 2021
Commit: f487dbae97f08e9830d202ca1fdd8fefacb78205
Author: Jacques Lucke
Date: Fri Sep 3 13:29:22 2021 +0200
Branches: temp-geometry-nodes-fields
https://developer.blender.org/rBf487dbae97f08e9830d202ca1fdd8fefacb78205
use GFieldRef where appropriate
===================================================================
M source/blender/functions/FN_field.hh
M source/blender/functions/intern/field.cc
M source/blender/functions/tests/FN_field_test.cc
===================================================================
diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh
index 29bb2cc25ba..482fdab0600 100644
--- a/source/blender/functions/FN_field.hh
+++ b/source/blender/functions/FN_field.hh
@@ -73,27 +73,35 @@ class FieldSource {
}
};
-/**
- * Descibes the output of a function. Generally corresponds to the combination of an output socket
- * and link combination in a node graph.
- */
-class GField {
- std::shared_ptr<FieldSource> source_;
+/** Common base class for fields to avoid declaring the same methods for #GField and #GFieldRef. */
+template<typename SourcePtr> class GFieldBase {
+ protected:
+ SourcePtr source_ = nullptr;
int source_output_index_ = 0;
- public:
- GField() = default;
-
- GField(std::shared_ptr<FieldSource> source, const int source_output_index = 0)
+ GFieldBase(SourcePtr source, const int source_output_index)
: source_(std::move(source)), source_output_index_(source_output_index)
{
}
+ public:
+ GFieldBase() = default;
+
operator bool() const
{
return source_ != nullptr;
}
+ friend bool operator==(const GFieldBase &a, const GFieldBase &b)
+ {
+ return &*a.source_ == &*b.source_ && a.source_output_index_ == b.source_output_index_;
+ }
+
+ uint64_t hash() const
+ {
+ return get_default_hash_2(source_, source_output_index_);
+ }
+
const fn::CPPType &cpp_type() const
{
return source_->cpp_type_of_output_index(source_output_index_);
@@ -120,6 +128,38 @@ class GField {
}
};
+/**
+ * Describes the output of a function. Generally corresponds to the combination of an output socket
+ * and link combination in a node graph.
+ */
+class GField : public GFieldBase<std::shared_ptr<FieldSource>> {
+ public:
+ GField() = default;
+
+ GField(std::shared_ptr<FieldSource> source, const int source_output_index = 0)
+ : GFieldBase<std::shared_ptr<FieldSource>>(std::move(source), source_output_index)
+ {
+ }
+};
+
+/** Same as #GField but is cheaper to copy/move around, because it does not contain a
+ * #std::shared_ptr.
+ */
+class GFieldRef : public GFieldBase<const FieldSource *> {
+ public:
+ GFieldRef() = default;
+
+ GFieldRef(const GField &field)
+ : GFieldBase<const FieldSource *>(&field.source(), field.source_output_index())
+ {
+ }
+
+ GFieldRef(const FieldSource &source, const int source_output_index = 0)
+ : GFieldBase<const FieldSource *>(&source, source_output_index)
+ {
+ }
+};
+
template<typename T> class Field : public GField {
public:
Field() = default;
@@ -235,14 +275,14 @@ class ContextFieldSource : public FieldSource {
};
Vector<const GVArray *> evaluate_fields(ResourceScope &scope,
- Span<const GField *> fields_to_evaluate,
+ Span<GFieldRef> fields_to_evaluate,
IndexMask mask,
const FieldContext &context,
Span<GVMutableArray *> dst_hints = {});
void evaluate_constant_field(const GField &field, void *r_value);
-void evaluate_fields_to_spans(Span<const GField *> fields_to_evaluate,
+void evaluate_fields_to_spans(Span<GFieldRef> fields_to_evaluate,
IndexMask mask,
const FieldContext &context,
Span<GMutableSpan> out_spans);
@@ -352,9 +392,9 @@ class FieldEvaluator : NonMovable, NonCopyable {
void evaluate()
{
BLI_assert_msg(!is_evaluated_, "Cannot evaluate fields twice.");
- Array<const GField *> fields(fields_to_evaluate_.size());
+ Array<GFieldRef> fields(fields_to_evaluate_.size());
for (const int i : fields_to_evaluate_.index_range()) {
- fields[i] = &fields_to_evaluate_[i];
+ fields[i] = fields_to_evaluate_[i];
}
evaluated_varrays_ = evaluate_fields(scope_, fields, mask_, context_, dst_hints_);
BLI_assert(fields_to_evaluate_.size() == evaluated_varrays_.size());
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 073908e6c1d..dbc355e1be3 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -24,62 +24,39 @@
namespace blender::fn {
-struct GFieldRef {
- const FieldSource *source;
- int index;
-
- GFieldRef(const FieldSource &source, const int index) : source(&source), index(index)
- {
- }
-
- GFieldRef(const GField &field) : source(&field.source()), index(field.source_output_index())
- {
- }
-
- uint64_t hash() const
- {
- return get_default_hash_2(*source, index);
- }
-
- friend bool operator==(const GFieldRef &a, const GFieldRef &b)
- {
- return *a.source == *b.source && a.index == b.index;
- }
-};
-
struct FieldGraphInfo {
- MultiValueMap<GFieldRef, const GField *> field_users;
+ MultiValueMap<GFieldRef, GFieldRef> field_users;
VectorSet<std::reference_wrapper<const ContextFieldSource>> deduplicated_context_sources;
};
-static FieldGraphInfo preprocess_field_graph(Span<const GField *> entry_fields)
+static FieldGraphInfo preprocess_field_graph(Span<GFieldRef> entry_fields)
{
FieldGraphInfo graph_info;
- Stack<const GField *> fields_to_check;
- Set<const GField *> handled_fields;
+ Stack<GFieldRef> fields_to_check;
+ Set<GFieldRef> handled_fields;
- for (const GField *field : entry_fields) {
+ for (GFieldRef field : entry_fields) {
if (handled_fields.add(field)) {
fields_to_check.push(field);
}
}
while (!fields_to_check.is_empty()) {
- const GField *field = fields_to_check.pop();
- if (field->has_context_source()) {
+ GFieldRef field = fields_to_check.pop();
+ if (field.has_context_source()) {
const ContextFieldSource &context_source = static_cast<const ContextFieldSource &>(
- field->source());
+ field.source());
graph_info.deduplicated_context_sources.add(context_source);
continue;
}
- BLI_assert(field->has_operation_source());
+ BLI_assert(field.has_operation_source());
const OperationFieldSource &operation = static_cast<const OperationFieldSource &>(
- field->source());
- for (const GField &operation_input : operation.inputs()) {
+ field.source());
+ for (const GFieldRef operation_input : operation.inputs()) {
graph_info.field_users.add(operation_input, field);
- if (handled_fields.add(&operation_input)) {
- fields_to_check.push(&operation_input);
+ if (handled_fields.add(operation_input)) {
+ fields_to_check.push(operation_input);
}
}
}
@@ -104,11 +81,11 @@ static Vector<const GVArray *> get_field_context_inputs(ResourceScope &scope,
return field_context_inputs;
}
-static Set<const GField *> find_varying_fields(const FieldGraphInfo &graph_info,
- Span<const GVArray *> field_context_inputs)
+static Set<GFieldRef> find_varying_fields(const FieldGraphInfo &graph_info,
+ Span<const GVArray *> field_context_inputs)
{
- Set<const GField *> found_fields;
- Stack<const GField *> fields_to_check;
+ Set<GFieldRef> found_fields;
+ Stack<GFieldRef> fields_to_check;
for (const int i : field_context_inputs.index_range()) {
const GVArray *varray = field_context_inputs[i];
if (varray->is_single()) {
@@ -116,17 +93,17 @@ static Set<const GField *> find_varying_fields(const FieldGraphInfo &graph_info,
}
const ContextFieldSource &context_source = graph_info.deduplicated_context_sources[i];
const GFieldRef context_source_field{context_source, 0};
- const Span<const GField *> users = graph_info.field_users.lookup(context_source_field);
- for (const GField *field : users) {
+ const Span<GFieldRef> users = graph_info.field_users.lookup(context_source_field);
+ for (const GFieldRef &field : users) {
if (found_fields.add(field)) {
fields_to_check.push(field);
}
}
}
while (!fields_to_check.is_empty()) {
- const GField *field = fields_to_check.pop();
- const Span<const GField *> users = graph_info.field_users.lookup(*field);
- for (const GField *field : users) {
+ GFieldRef field = fields_to_check.pop();
+ const Span<GFieldRef> users = graph_info.field_users.lookup(field);
+ for (GFieldRef field : users) {
if (found_fields.add(field)) {
fields_to_check.push(field);
}
@@ -138,7 +115,7 @@ static Set<const GField *> find_varying_fields(const FieldGraphInfo &graph_info,
static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
ResourceScope &scope,
const FieldGraphInfo &graph_info,
- Span<const GField *> output_fields)
+ Span<GFieldRef> output_fields)
{
MFProcedureBuilder builder{procedure};
Map<GFieldRef, MFVariable *> variable_by_field;
@@ -149,16 +126,16 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
}
struct FieldWithIndex {
- const GField *field;
+ GFieldRef field;
int current_input_index = 0;
};
- for (const GField *field : output_fields) {
+ for (GFieldRef field : output_fields) {
Stack<FieldWithIndex> fields_to_check;
fields_to_check.push({field, 0});
while (!fields_to_check.is_empty()) {
FieldWithIndex &field_with_index = fields_to_check.peek();
- const GField &field = *field_with_index.field;
+ const GFieldRef &field = field_with_index.field;
if (variable_by_field.contains(field)) {
fields_to_check.pop();
continue;
@@ -170,7 +147,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure,
const Span<GField> operation_inputs = operation_field_source.inputs();
if (field_with_index.current_input_index < operation_inputs.size()) {
/* Push next input. */
- fields_to_check.push({&operation_inputs[field_with_index.current_input_index], 0});
+ fiel
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list