[Bf-blender-cvs] [610ec34c1f7] master: Geometry Nodes: Improve performance writing to vertex groups

Hans Goudey noreply at git.blender.org
Thu Mar 24 05:27:37 CET 2022


Commit: 610ec34c1f7dbd28f0e3f31b3bb79c52fa97d2cb
Author: Hans Goudey
Date:   Wed Mar 23 23:27:26 2022 -0500
Branches: master
https://developer.blender.org/rB610ec34c1f7dbd28f0e3f31b3bb79c52fa97d2cb

Geometry Nodes: Improve performance writing to vertex groups

In a test file from T96282, this commit reduces the runtime of the
delete geometry node from 82 ms to 23 ms, a 3.6x improvement.
Writing to vertex groups in other cases should be faster too.

The largest improvement comes from not writing a new weight
of zero if the vertex is not in the group. This mirrors the behavior
of custom data interpolation in `layerInterp_mdeformvert`.
Other improvements come from using `set_all` for writing
output attributes and implementing that method for vertex groups.

I also implemented `materialize` methods. Though I didn't obverse
an improvement from this, I think it's best to remove virtual method
call overhead where it's simple to do so.

The test file for the delete geometry node needs to be updated.
These methods could be parallelized too, but better to do that later.

Differential Revision: https://developer.blender.org/D14420

===================================================================

M	source/blender/blenkernel/intern/geometry_component_mesh.cc
M	source/blender/blenlib/intern/generic_virtual_array.cc

===================================================================

diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 76c8a0054b3..2bfe984462c 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -944,20 +944,71 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
     if (dverts_ == nullptr) {
       return 0.0f;
     }
-    const MDeformVert &dvert = dverts_[index];
-    for (const MDeformWeight &weight : Span(dvert.dw, dvert.totweight)) {
-      if (weight.def_nr == dvert_index_) {
-        return weight.weight;
-      }
+    if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
+      return weight->weight;
     }
     return 0.0f;
-    ;
   }
 
   void set(const int64_t index, const float value) override
   {
-    MDeformWeight *weight = BKE_defvert_ensure_index(&dverts_[index], dvert_index_);
-    weight->weight = value;
+    MDeformVert &dvert = dverts_[index];
+    if (value == 0.0f) {
+      if (MDeformWeight *weight = this->find_weight_at_index(index)) {
+        weight->weight = 0.0f;
+      }
+    }
+    else {
+      MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_);
+      weight->weight = value;
+    }
+  }
+
+  void set_all(Span<float> src) override
+  {
+    for (const int64_t index : src.index_range()) {
+      this->set(index, src[index]);
+    }
+  }
+
+  void materialize(IndexMask mask, MutableSpan<float> r_span) const override
+  {
+    if (dverts_ == nullptr) {
+      return r_span.fill_indices(mask, 0.0f);
+    }
+    for (const int64_t index : mask) {
+      if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
+        r_span[index] = weight->weight;
+      }
+      else {
+        r_span[index] = 0.0f;
+      }
+    }
+  }
+
+  void materialize_to_uninitialized(IndexMask mask, MutableSpan<float> r_span) const override
+  {
+    this->materialize(mask, r_span);
+  }
+
+ private:
+  MDeformWeight *find_weight_at_index(const int64_t index)
+  {
+    for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) {
+      if (weight.def_nr == dvert_index_) {
+        return &weight;
+      }
+    }
+    return nullptr;
+  }
+  const MDeformWeight *find_weight_at_index(const int64_t index) const
+  {
+    for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) {
+      if (weight.def_nr == dvert_index_) {
+        return &weight;
+      }
+    }
+    return nullptr;
   }
 };
 
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index c6abf3624e1..8a6ef8e792f 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -391,10 +391,7 @@ void GVMutableArray_GSpan::save()
   if (data_ != owned_data_) {
     return;
   }
-  const int64_t element_size = type_->size();
-  for (int64_t i : IndexRange(size_)) {
-    varray_.set_by_copy(i, POINTER_OFFSET(owned_data_, element_size * i));
-  }
+  varray_.set_all(owned_data_);
 }
 
 void GVMutableArray_GSpan::disable_not_applied_warning()



More information about the Bf-blender-cvs mailing list