[Bf-blender-cvs] [7688f0ace7a] master: Curves: Move type conversion to the geometry module

Hans Goudey noreply at git.blender.org
Tue Jul 5 23:18:01 CEST 2022


Commit: 7688f0ace7a6c45aaa8304d2a26a760be0056aa6
Author: Hans Goudey
Date:   Tue Jul 5 15:51:12 2022 -0500
Branches: master
https://developer.blender.org/rB7688f0ace7a6c45aaa8304d2a26a760be0056aa6

Curves: Move type conversion to the geometry module

This helps to separate concerns, and makes the functionality
available for edit mode.

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

M	source/blender/geometry/CMakeLists.txt
A	source/blender/geometry/GEO_set_curve_type.hh
A	source/blender/geometry/intern/set_curve_type.cc
M	source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc

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

diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt
index f0fb5c5c9af..21b2071d0e6 100644
--- a/source/blender/geometry/CMakeLists.txt
+++ b/source/blender/geometry/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC
   intern/realize_instances.cc
   intern/resample_curves.cc
   intern/reverse_uv_sampler.cc
+  intern/set_curve_type.cc
   intern/uv_parametrizer.c
 
   GEO_add_curves_on_mesh.hh
@@ -35,6 +36,7 @@ set(SRC
   GEO_realize_instances.hh
   GEO_resample_curves.hh
   GEO_reverse_uv_sampler.hh
+  GEO_set_curve_type.hh
   GEO_uv_parametrizer.h
 )
 
diff --git a/source/blender/geometry/GEO_set_curve_type.hh b/source/blender/geometry/GEO_set_curve_type.hh
new file mode 100644
index 00000000000..f7ac8be5889
--- /dev/null
+++ b/source/blender/geometry/GEO_set_curve_type.hh
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "DNA_curves_types.h"
+
+#include "BLI_function_ref.hh"
+#include "BLI_index_mask.hh"
+
+struct Curves;
+struct CurveComponent;
+
+namespace blender::bke {
+class CurvesGeometry;
+}
+
+namespace blender::geometry {
+
+/**
+ * Try the conversion to the #dst_type-- avoiding the majority of the work done in
+ * #convert_curves by modifying an existing object in place rather than creating a new one.
+ *
+ * \note This function is necessary because attributes do not have proper support for CoW.
+ *
+ * \param get_writable_curves_fn: Should return the write-able curves to change directly if
+ * possible. This is a function in order to avoid the cost of retrieval when unnecessary.
+ */
+bool try_curves_conversion_in_place(IndexMask selection,
+                                    CurveType dst_type,
+                                    FunctionRef<Curves &()> get_writable_curves_fn);
+
+/**
+ * Change the types of the selected curves, potentially changing the total point count.
+ */
+Curves *convert_curves(const CurveComponent &src_component,
+                       const bke::CurvesGeometry &src_curves,
+                       IndexMask selection,
+                       CurveType dst_type);
+
+}  // namespace blender::geometry
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc b/source/blender/geometry/intern/set_curve_type.cc
similarity index 80%
copy from source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
copy to source/blender/geometry/intern/set_curve_type.cc
index 5c836391abe..d7a5bc9b27d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc
+++ b/source/blender/geometry/intern/set_curve_type.cc
@@ -1,41 +1,15 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
-#include <numeric>
-
 #include "BKE_attribute_math.hh"
 #include "BKE_curves.hh"
 #include "BKE_curves_utils.hh"
+#include "BKE_geometry_set.hh"
 
 #include "BLI_task.hh"
 
-#include "UI_interface.h"
-#include "UI_resources.h"
-
-#include "node_geometry_util.hh"
-
-namespace blender::nodes::node_geo_curve_spline_type_cc {
-
-NODE_STORAGE_FUNCS(NodeGeometryCurveSplineType)
-
-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).hide_value().supports_field();
-  b.add_output<decl::Geometry>(N_("Curve"));
-}
-
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
-  uiItemR(layout, ptr, "spline_type", 0, "", ICON_NONE);
-}
+#include "GEO_set_curve_type.hh"
 
-static void node_init(bNodeTree *UNUSED(tree), bNode *node)
-{
-  NodeGeometryCurveSplineType *data = MEM_cnew<NodeGeometryCurveSplineType>(__func__);
-
-  data->spline_type = CURVE_TYPE_POLY;
-  node->storage = data;
-}
+namespace blender::geometry {
 
 /**
  * This function answers the question about possible conversion method for NURBS-to-Bezier. In
@@ -303,11 +277,20 @@ static int to_nurbs_size(const CurveType src_type, const int src_size)
   }
 }
 
+static void retrieve_curve_sizes(const bke::CurvesGeometry &curves, MutableSpan<int> sizes)
+{
+  threading::parallel_for(curves.curves_range(), 4096, [&](IndexRange range) {
+    for (const int i : range) {
+      sizes[i] = curves.points_for_curve(i).size();
+    }
+  });
+}
+
 struct GenericAttributes : NonCopyable, NonMovable {
   Vector<GSpan> src;
   Vector<GMutableSpan> dst;
 
-  Vector<OutputAttribute> attributes;
+  Vector<bke::OutputAttribute> attributes;
 };
 
 static void retrieve_generic_point_attributes(const CurveComponent &src_component,
@@ -315,7 +298,7 @@ static void retrieve_generic_point_attributes(const CurveComponent &src_componen
                                               GenericAttributes &attributes)
 {
   src_component.attribute_foreach(
-      [&](const AttributeIDRef &id, const AttributeMetaData meta_data) {
+      [&](const bke::AttributeIDRef &id, const AttributeMetaData meta_data) {
         if (meta_data.domain != ATTR_DOMAIN_POINT) {
           /* Curve domain attributes are all copied directly to the result in one step. */
           return true;
@@ -330,7 +313,7 @@ static void retrieve_generic_point_attributes(const CurveComponent &src_componen
         BLI_assert(src_attribute);
         attributes.src.append(src_attribute.get_internal_span());
 
-        OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
+        bke::OutputAttribute dst_attribute = dst_component.attribute_try_get_for_output_only(
             id, ATTR_DOMAIN_POINT, meta_data.data_type);
         attributes.dst.append(dst_attribute.as_span());
         attributes.attributes.append(std::move(dst_attribute));
@@ -339,28 +322,46 @@ static void retrieve_generic_point_attributes(const CurveComponent &src_componen
       });
 }
 
-static void convert_to_bezier(const CurveComponent &src_component,
-                              const bke::CurvesGeometry &src_curves,
-                              const IndexMask selection,
-                              CurveComponent &dst_component,
-                              bke::CurvesGeometry &dst_curves)
+static Curves *create_result_curves(const bke::CurvesGeometry &src_curves,
+                                    const IndexMask selection,
+                                    const CurveType dst_type)
 {
-  const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert(
-      src_curves.curves_range());
+  Curves *dst_curves_id = bke::curves_new_nomain(0, src_curves.curves_num());
+  bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry);
+  CurveComponent dst_component;
+  dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable);
+  /* Directly copy curve attributes, since they stay the same (except for curve types). */
+  CustomData_copy(&src_curves.curve_data,
+                  &dst_curves.curve_data,
+                  CD_MASK_ALL,
+                  CD_DUPLICATE,
+                  src_curves.curves_num());
+
+  dst_curves.fill_curve_types(selection, dst_type);
+
+  return dst_curves_id;
+}
 
+static Curves *convert_curves_to_bezier(const CurveComponent &src_component,
+                                        const bke::CurvesGeometry &src_curves,
+                                        const IndexMask selection)
+{
   const VArray<int8_t> src_knot_modes = src_curves.nurbs_knots_modes();
   const VArray<int8_t> src_types = src_curves.curve_types();
   const VArray<bool> src_cyclic = src_curves.cyclic();
   const Span<float3> src_positions = src_curves.positions();
 
+  Curves *dst_curves_id = create_result_curves(src_curves, selection, CURVE_TYPE_BEZIER);
+  bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry);
+  CurveComponent dst_component;
+  dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable);
+
   MutableSpan<int> dst_offsets = dst_curves.offsets_for_write();
-  bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_curves.offsets_for_write());
+  retrieve_curve_sizes(src_curves, dst_curves.offsets_for_write());
   threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) {
     for (const int i : selection.slice(range)) {
-      const CurveType type = CurveType(src_types[i]);
-      const KnotsMode knots_mode = KnotsMode(src_knot_modes[i]);
-      const IndexRange points = src_curves.points_for_curve(i);
-      dst_offsets[i] = to_bezier_size(type, src_cyclic[i], knots_mode, points.size());
+      dst_offsets[i] = to_bezier_size(
+          CurveType(src_types[i]), src_cyclic[i], KnotsMode(src_knot_modes[i]), dst_offsets[i]);
     }
   });
   bke::curves::accumulate_counts_to_offsets(dst_offsets);
@@ -485,35 +486,39 @@ static void convert_to_bezier(const CurveComponent &src_component,
                                      bezier_to_bezier,
                                      nurbs_to_bezier);
 
+  const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert(
+      src_curves.curves_range());
+
   for (const int i : attributes.src.index_range()) {
     bke::curves::copy_point_data(
         src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]);
   }
 
-  for (OutputAttribute &attribute : attributes.attributes) {
+  for (bke::OutputAttribute &attribute : attributes.attributes) {
     attribute.save();
   }
+
+  return dst_curves_id;
 }
 
-static void convert_to_nurbs(const CurveComponent &src_component,
-                             const bke::CurvesGeometry &src_curves,
-                             const IndexMask selection,
-                             CurveComponent &dst_component,
-                             bke::CurvesGeometry &dst_curves)
+static Curves *convert_curves_to_nurbs(const CurveComponent &src_component,
+                                       const bke::CurvesGeometry &src_curves,
+                                       const IndexMask selection)
 {
-  const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert(
-      src_curves.curves_range());
-
   const VArray<int8_t> src_types = src_curves.curve_types();
   const VArray<bool> src_cyclic = src_curves.cyclic();
   const Span<float3> src_positions = src_curves.positions();
 
+  Curves *dst_cur

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list