[Bf-blender-cvs] [000e722c7d9] master: Geometry Nodes: Optimize start point case of Points of Curve node

Hans Goudey noreply at git.blender.org
Fri Jan 27 17:00:17 CET 2023


Commit: 000e722c7d99320ce51d1487147a2f275ae44b16
Author: Hans Goudey
Date:   Fri Jan 27 09:44:30 2023 -0600
Branches: master
https://developer.blender.org/rB000e722c7d99320ce51d1487147a2f275ae44b16

Geometry Nodes: Optimize start point case of Points of Curve node

In the node groups for T103730, the "Points of Curve" node is often used to
retrieve the root point of every curve. Since the curve point offsets array
already contains that data directly, we can detect this as a special case and
avoid all the other work.

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

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

M	source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc

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

diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
index 8d9e4a07a76..820fa4856a4 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc
@@ -174,6 +174,57 @@ class CurvePointCountInput final : public bke::CurvesFieldInput {
   }
 };
 
+/**
+ * The node is often used to retrieve the root point of the curve. If the curve indices are in
+ * order, the sort weights have no effect, and the sort index is the first point, then we can just
+ * return the curve offsets as a span directly.
+ */
+static bool use_start_point_special_case(const Field<int> &curve_index,
+                                         const Field<int> &sort_index,
+                                         const Field<float> &sort_weights)
+{
+  if (!dynamic_cast<const fn::IndexFieldInput *>(&curve_index.node())) {
+    return false;
+  }
+  if (sort_index.node().depends_on_input() || sort_weights.node().depends_on_input()) {
+    return false;
+  }
+  return fn::evaluate_constant_field(sort_index) == 0;
+}
+
+class CurveStartPointInput final : public bke::CurvesFieldInput {
+ public:
+  CurveStartPointInput() : bke::CurvesFieldInput(CPPType::get<int>(), "Point of Curve")
+  {
+    category_ = Category::Generated;
+  }
+
+  GVArray get_varray_for_context(const bke::CurvesGeometry &curves,
+                                 const eAttrDomain /*domain*/,
+                                 const IndexMask /*mask*/) const final
+  {
+    return VArray<int>::ForSpan(curves.offsets());
+  }
+
+  uint64_t hash() const final
+  {
+    return 2938459815345;
+  }
+
+  bool is_equal_to(const fn::FieldNode &other) const final
+  {
+    if (dynamic_cast<const CurveStartPointInput *>(&other)) {
+      return true;
+    }
+    return false;
+  }
+
+  std::optional<eAttrDomain> preferred_domain(const bke::CurvesGeometry & /*curves*/)
+  {
+    return ATTR_DOMAIN_CURVE;
+  }
+};
+
 static void node_geo_exec(GeoNodeExecParams params)
 {
   const Field<int> curve_index = params.extract_input<Field<int>>("Curve Index");
@@ -185,11 +236,16 @@ static void node_geo_exec(GeoNodeExecParams params)
                           ATTR_DOMAIN_CURVE)));
   }
   if (params.output_is_required("Point Index")) {
-    params.set_output("Point Index",
-                      Field<int>(std::make_shared<PointsOfCurveInput>(
-                          curve_index,
-                          params.extract_input<Field<int>>("Sort Index"),
-                          params.extract_input<Field<float>>("Weights"))));
+    Field<int> sort_index = params.extract_input<Field<int>>("Sort Index");
+    Field<int> sort_weight = params.extract_input<Field<float>>("Weights");
+    if (use_start_point_special_case(curve_index, sort_index, sort_weight)) {
+      params.set_output("Point Index", Field<int>(std::make_shared<CurveStartPointInput>()));
+    }
+    else {
+      params.set_output("Point Index",
+                        Field<int>(std::make_shared<PointsOfCurveInput>(
+                            curve_index, std::move(sort_index), std::move(sort_weight))));
+    }
   }
 }



More information about the Bf-blender-cvs mailing list