[Bf-blender-cvs] [e0e95f78957] master: Refactor: Move resample curves code to the geometry module

Hans Goudey noreply at git.blender.org
Mon May 9 17:33:59 CEST 2022


Commit: e0e95f789576fec43550ef8aae8ae94151f7967f
Author: Hans Goudey
Date:   Mon May 9 17:33:30 2022 +0200
Branches: master
https://developer.blender.org/rBe0e95f789576fec43550ef8aae8ae94151f7967f

Refactor: Move resample curves code to the geometry module

This commit moves the code for the resample curves node to the geometry
module, to allow reusing it in any editor. Split from D14870.

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

M	source/blender/blenkernel/BKE_curves.hh
M	source/blender/blenkernel/intern/curves.cc
M	source/blender/geometry/CMakeLists.txt
A	source/blender/geometry/GEO_resample_curves.hh
A	source/blender/geometry/intern/resample_curves.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc

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

diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index bf2d50f63be..8ef7d2811b1 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -671,6 +671,7 @@ void interpolate_to_evaluated(const BasisCache &basis_cache,
 }  // namespace curves
 
 Curves *curves_new_nomain(int points_num, int curves_num);
+Curves *curves_new_nomain(CurvesGeometry curves);
 
 /**
  * Create a new curves data-block containing a single curve with the given length and type.
diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc
index 1df1492bac1..bcfd6206a78 100644
--- a/source/blender/blenkernel/intern/curves.cc
+++ b/source/blender/blenkernel/intern/curves.cc
@@ -379,4 +379,11 @@ Curves *curves_new_nomain_single(const int points_num, const CurveType type)
   return curves;
 }
 
+Curves *curves_new_nomain(CurvesGeometry curves)
+{
+  Curves *curves_id = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
+  bke::CurvesGeometry::wrap(curves_id->geometry) = std::move(curves);
+  return curves_id;
+}
+
 }  // namespace blender::bke
diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt
index 8716d6c8f67..9dcacb13536 100644
--- a/source/blender/geometry/CMakeLists.txt
+++ b/source/blender/geometry/CMakeLists.txt
@@ -19,12 +19,14 @@ set(SRC
   intern/mesh_to_curve_convert.cc
   intern/point_merge_by_distance.cc
   intern/realize_instances.cc
+  intern/resample_curves.cc
   intern/uv_parametrizer.c
 
   GEO_mesh_merge_by_distance.hh
   GEO_mesh_to_curve.hh
   GEO_point_merge_by_distance.hh
   GEO_realize_instances.hh
+  GEO_resample_curves.hh
   GEO_uv_parametrizer.h
 )
 
diff --git a/source/blender/geometry/GEO_resample_curves.hh b/source/blender/geometry/GEO_resample_curves.hh
new file mode 100644
index 00000000000..7cfb5dadde6
--- /dev/null
+++ b/source/blender/geometry/GEO_resample_curves.hh
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "FN_field.hh"
+
+#include "BKE_geometry_set.hh"
+
+struct Curves;
+
+namespace blender::geometry {
+
+/**
+ * Create new curves where the selected curves have been resampled with a number of uniform-length
+ * samples defined by the count field. Interpolate attributes to the result, with an accuracy that
+ * depends on the curve's resolution parameter.
+ *
+ * \note The values provided by the #count_field are clampled to 1 or greater.
+ */
+Curves *resample_to_count(const CurveComponent &src_component,
+                          const fn::Field<bool> &selection_field,
+                          const fn::Field<int> &count_field);
+
+/**
+ * Create new curves resampled to make each segment have the length specified by the
+ * #segment_length field input, rounded to make the length of each segment the same.
+ * The accuracy will depend on the curve's resolution parameter.
+ */
+Curves *resample_to_length(const CurveComponent &src_component,
+                           const fn::Field<bool> &selection_field,
+                           const fn::Field<float> &segment_length_field);
+
+/**
+ * Evaluate each selected curve to its implicit evaluated points.
+ */
+Curves *resample_to_evaluated(const CurveComponent &src_component,
+                              const fn::Field<bool> &selection_field);
+
+}  // namespace blender::geometry
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/geometry/intern/resample_curves.cc
similarity index 71%
copy from source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
copy to source/blender/geometry/intern/resample_curves.cc
index 471d6af560f..4f1fbfd29d1 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/geometry/intern/resample_curves.cc
@@ -1,66 +1,55 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
-#include "BLI_array.hh"
-#include "BLI_index_mask_ops.hh"
 #include "BLI_length_parameterize.hh"
 #include "BLI_task.hh"
-#include "BLI_timeit.hh"
+
+#include "FN_field.hh"
+#include "FN_multi_function_builder.hh"
 
 #include "BKE_attribute_math.hh"
 #include "BKE_curves.hh"
+#include "BKE_geometry_fields.hh"
 
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_curve_resample_cc {
-
-NODE_STORAGE_FUNCS(NodeGeometryCurveResample)
+#include "GEO_resample_curves.hh"
 
-static void node_declare(NodeDeclarationBuilder &b)
-{
-  b.add_input<decl::Geometry>(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE);
-  b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
-  b.add_input<decl::Int>(N_("Count")).default_value(10).min(1).max(100000).supports_field();
-  b.add_input<decl::Float>(N_("Length"))
-      .default_value(0.1f)
-      .min(0.01f)
-      .supports_field()
-      .subtype(PROP_DISTANCE);
-  b.add_output<decl::Geometry>(N_("Curve"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
-  uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
-}
+namespace blender::geometry {
 
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
+static fn::Field<int> get_count_input_max_one(const fn::Field<int> &count_field)
 {
-  NodeGeometryCurveResample *data = MEM_cnew<NodeGeometryCurveResample>(__func__);
-
-  data->mode = GEO_NODE_CURVE_RESAMPLE_COUNT;
-  node->storage = data;
+  static fn::CustomMF_SI_SO<int, int> max_one_fn(
+      "Clamp Above One",
+      [](int value) { return std::max(1, value); },
+      fn::CustomMF_presets::AllSpanOrSingle());
+  auto clamp_op = std::make_shared<fn::FieldOperation>(
+      fn::FieldOperation(max_one_fn, {count_field}));
+
+  return fn::Field<int>(std::move(clamp_op));
 }
 
-static void node_update(bNodeTree *ntree, bNode *node)
+static fn::Field<int> get_count_input_from_length(const fn::Field<float> &length_field)
 {
-  const NodeGeometryCurveResample &storage = node_storage(*node);
-  const GeometryNodeCurveResampleMode mode = (GeometryNodeCurveResampleMode)storage.mode;
-
-  bNodeSocket *count_socket = ((bNodeSocket *)node->inputs.first)->next->next;
-  bNodeSocket *length_socket = count_socket->next;
-
-  nodeSetSocketAvailability(ntree, count_socket, mode == GEO_NODE_CURVE_RESAMPLE_COUNT);
-  nodeSetSocketAvailability(ntree, length_socket, mode == GEO_NODE_CURVE_RESAMPLE_LENGTH);
+  static fn::CustomMF_SI_SI_SO<float, float, int> get_count_fn(
+      "Length Input to Count",
+      [](const float curve_length, const float sample_length) {
+        /* Find the number of sampled segments by dividing the total length by
+         * the sample length. Then there is one more sampled point than segment. */
+        const int count = int(curve_length / sample_length) + 1;
+        return std::max(1, count);
+      },
+      fn::CustomMF_presets::AllSpanOrSingle());
+
+  auto get_count_op = std::make_shared<fn::FieldOperation>(fn::FieldOperation(
+      get_count_fn,
+      {fn::Field<float>(std::make_shared<bke::CurveLengthFieldInput>()), length_field}));
+
+  return fn::Field<int>(std::move(get_count_op));
 }
 
 /**
  * Return true if the attribute should be copied/interpolated to the result curves.
  * Don't output attributes that correspond to curve types that have no curves in the result.
  */
-static bool interpolate_attribute_to_curves(const AttributeIDRef &attribute_id,
+static bool interpolate_attribute_to_curves(const bke::AttributeIDRef &attribute_id,
                                             const std::array<int, CURVE_TYPES_NUM> &type_counts)
 {
   if (!attribute_id.is_named()) {
@@ -82,7 +71,7 @@ static bool interpolate_attribute_to_curves(const AttributeIDRef &attribute_id,
 /**
  * Return true if the attribute should be copied to poly curves.
  */
-static bool interpolate_attribute_to_poly_curve(const AttributeIDRef &attribute_id)
+static bool interpolate_attribute_to_poly_curve(const bke::AttributeIDRef &attribute_id)
 {
   static const Set<StringRef> no_interpolation{{
       "handle_type_left",
@@ -97,12 +86,12 @@ static bool interpolate_attribute_to_poly_curve(const AttributeIDRef &attribute_
 /**
  * Retrieve spans from source and result attributes.
  */
-static void retrieve_attribute_spans(const Span<AttributeIDRef> ids,
+static void retrieve_attribute_spans(const Span<bke::AttributeIDRef> ids,
                                      const CurveComponent &src_component,
                                      CurveComponent &dst_component,
                                      Vector<GSpan> &src,
                                      Vector<GMutableSpan> &dst,
-                                     Vector<OutputAttribute> &dst_attributes)
+                                     Vector<bke::OutputAttribute> &dst_attributes)
 {
   for (const int i : ids.index_range()) {
     GVArray src_attribute = src_component.attribute_try_get_for_read(ids[i], ATTR_DOMAIN_POINT);
@@ -110,7 +99,7 @@ static void retrieve_attribute_spans(const Span<AttributeIDRef> ids,
     src.append(src_attribute.get_internal_span());
 
     const CustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type());
-    OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
+    bke::OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
         ids[i], ATTR_DOMAIN_POINT, data_type);
     dst.append(dst_attribute.as_span());
     dst_attributes.append(std::move(dst_attribute));
@@ -121,7 +110,7 @@ struct AttributesForInterpolation : NonCopyable, NonMovable {
   Vector<GSpan> src;
   Vector<GMutableSpan> dst;
 
-  Vector<OutputAttribute> dst_attributes;
+  Vector<bke::OutputAttribute> dst_attributes;
 
   Vector<GSpan> src_no_interpolation;
   Vector<GMutableSpan> dst_no_interpolation;
@@ -134,13 +123,13 @@ static void gather_point_attributes_to_interpolate(const CurveComponent &src_com
                                                    CurveComponent &dst_component,
                                                    AttributesForInterpolation &result)
 {
-  const Curves &dst_curves_id = *dst_component.get_for_read();
-  const bke::CurvesGeometry 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list