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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs