[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