diff options
author | Hans Goudey <h.goudey@me.com> | 2022-07-19 18:14:46 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-07-19 18:16:30 +0300 |
commit | 6a1ab4747b7758017721cb191046a9db800f7894 (patch) | |
tree | a3e28d26c96c2070b231bcb6c5f6a9b0409361aa /source/blender/geometry/intern | |
parent | 9246ff373a19df24255d924979c78793f97b2834 (diff) |
Geometry Nodes: Copy parameters when copying a curves data-block
Previously, things like materials, symmetry, and selection options
stored on `Curves` weren't copied to the result in nodes like the
subdivide and resample nodes. Now they are, which fixes some
unexpected behavior and allows visualization of the sculpt mode
selection.
In the realize instances and join nodes the behavior is the same as
for meshes, the parameters are taken from the first (top) input.
I also refactored some functions to return a `CurvesGeometry` by-value,
which makes it the responsibility of the node to copy the parameters.
That should make the algorithms more reusable in other situations.
Differential Revision: https://developer.blender.org/D15408
Diffstat (limited to 'source/blender/geometry/intern')
4 files changed, 46 insertions, 96 deletions
diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 681dfd15137..fdacb174462 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -30,13 +30,12 @@ static void copy_with_map(const VArray<T> &src, Span<int> map, MutableSpan<T> ds }); } -static Curves *create_curve_from_vert_indices(const MeshComponent &mesh_component, - const Span<int> vert_indices, - const Span<int> curve_offsets, - const IndexRange cyclic_curves) +static bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, + const Span<int> vert_indices, + const Span<int> curve_offsets, + const IndexRange cyclic_curves) { - Curves *curves_id = bke::curves_new_nomain(vert_indices.size(), curve_offsets.size()); - bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + bke::CurvesGeometry curves(vert_indices.size(), curve_offsets.size()); curves.offsets_for_write().drop_back(1).copy_from(curve_offsets); curves.offsets_for_write().last() = vert_indices.size(); curves.fill_curve_types(CURVE_TYPE_POLY); @@ -44,8 +43,8 @@ static Curves *create_curve_from_vert_indices(const MeshComponent &mesh_componen curves.cyclic_for_write().fill(false); curves.cyclic_for_write().slice(cyclic_curves).fill(true); + const bke::AttributeAccessor mesh_attributes = bke::mesh_attributes(mesh); bke::MutableAttributeAccessor curves_attributes = curves.attributes_for_write(); - const bke::AttributeAccessor mesh_attributes = *mesh_component.attributes(); Set<bke::AttributeIDRef> source_attribute_ids = mesh_attributes.all_ids(); @@ -76,7 +75,7 @@ static Curves *create_curve_from_vert_indices(const MeshComponent &mesh_componen }); } - return curves_id; + return curves; } struct CurveFromEdgesOutput { @@ -220,16 +219,14 @@ static Vector<std::pair<int, int>> get_selected_edges(const Mesh &mesh, const In return selected_edges; } -Curves *mesh_to_curve_convert(const MeshComponent &mesh_component, const IndexMask selection) +bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh, const IndexMask selection) { - const Mesh &mesh = *mesh_component.get_for_read(); - Vector<std::pair<int, int>> selected_edges = get_selected_edges(*mesh_component.get_for_read(), - selection); + Vector<std::pair<int, int>> selected_edges = get_selected_edges(mesh, selection); CurveFromEdgesOutput output = edges_to_curve_point_indices({mesh.mvert, mesh.totvert}, selected_edges); return create_curve_from_vert_indices( - mesh_component, output.vert_indices, output.curve_offsets, output.cyclic_curves); + mesh, output.vert_indices, output.curve_offsets, output.cyclic_curves); } } // namespace blender::geometry diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 66b856ee0c4..25bcead09b4 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -1238,6 +1238,11 @@ static void execute_realize_curve_tasks(const RealizeInstancesOptions &options, dst_component.replace(dst_curves_id); bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); + /* Copy settings from the first input geometry set with curves. */ + const RealizeCurveTask &first_task = tasks.first(); + const Curves &first_curves_id = *first_task.curve_info->curves; + bke::curves_copy_parameters(first_curves_id, *dst_curves_id); + /* Prepare id attribute. */ SpanAttributeWriter<int> point_ids; if (all_curves_info.create_id_attribute) { diff --git a/source/blender/geometry/intern/set_curve_type.cc b/source/blender/geometry/intern/set_curve_type.cc index 08888a74973..40ee2488a4b 100644 --- a/source/blender/geometry/intern/set_curve_type.cc +++ b/source/blender/geometry/intern/set_curve_type.cc @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_attribute.hh" #include "BKE_attribute_math.hh" #include "BKE_curves.hh" #include "BKE_curves_utils.hh" -#include "BKE_geometry_set.hh" #include "BLI_task.hh" @@ -322,39 +322,16 @@ static void retrieve_generic_point_attributes(const bke::AttributeAccessor &src_ }); } -static Curves *create_result_curves(const bke::CurvesGeometry &src_curves, - const IndexMask selection, - const CurveType dst_type) -{ - 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) +static bke::CurvesGeometry convert_curves_to_bezier(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); + bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); + dst_curves.fill_curve_types(selection, CURVE_TYPE_BEZIER); MutableSpan<int> dst_offsets = dst_curves.offsets_for_write(); retrieve_curve_sizes(src_curves, dst_curves.offsets_for_write()); @@ -367,8 +344,8 @@ static Curves *convert_curves_to_bezier(const CurveComponent &src_component, bke::curves::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); - const bke::AttributeAccessor src_attributes = *src_component.attributes(); - bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write(); + const bke::AttributeAccessor src_attributes = src_curves.attributes(); + bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); GenericAttributes attributes; retrieve_generic_point_attributes(src_attributes, dst_attributes, attributes); @@ -501,21 +478,18 @@ static Curves *convert_curves_to_bezier(const CurveComponent &src_component, attribute.finish(); } - return dst_curves_id; + return dst_curves; } -static Curves *convert_curves_to_nurbs(const CurveComponent &src_component, - const bke::CurvesGeometry &src_curves, - const IndexMask selection) +static bke::CurvesGeometry convert_curves_to_nurbs(const bke::CurvesGeometry &src_curves, + const IndexMask selection) { 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_NURBS); - bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry); - CurveComponent dst_component; - dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable); + bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); + dst_curves.fill_curve_types(selection, CURVE_TYPE_NURBS); MutableSpan<int> dst_offsets = dst_curves.offsets_for_write(); retrieve_curve_sizes(src_curves, dst_curves.offsets_for_write()); @@ -527,8 +501,8 @@ static Curves *convert_curves_to_nurbs(const CurveComponent &src_component, bke::curves::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); - const bke::AttributeAccessor src_attributes = *src_component.attributes(); - bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write(); + const bke::AttributeAccessor src_attributes = src_curves.attributes(); + bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); GenericAttributes attributes; retrieve_generic_point_attributes(src_attributes, dst_attributes, attributes); @@ -669,7 +643,7 @@ static Curves *convert_curves_to_nurbs(const CurveComponent &src_component, attribute.finish(); } - return dst_curves_id; + return dst_curves; } static bke::CurvesGeometry convert_curves_trivial(const bke::CurvesGeometry &src_curves, @@ -682,33 +656,31 @@ static bke::CurvesGeometry convert_curves_trivial(const bke::CurvesGeometry &src return dst_curves; } -Curves *convert_curves(const CurveComponent &src_component, - const bke::CurvesGeometry &src_curves, - const IndexMask selection, - const CurveType dst_type) +bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves, + const IndexMask selection, + const CurveType dst_type) { switch (dst_type) { case CURVE_TYPE_CATMULL_ROM: case CURVE_TYPE_POLY: - return bke::curves_new_nomain(convert_curves_trivial(src_curves, selection, dst_type)); + return convert_curves_trivial(src_curves, selection, dst_type); case CURVE_TYPE_BEZIER: - return convert_curves_to_bezier(src_component, src_curves, selection); + return convert_curves_to_bezier(src_curves, selection); case CURVE_TYPE_NURBS: - return convert_curves_to_nurbs(src_component, src_curves, selection); + return convert_curves_to_nurbs(src_curves, selection); } BLI_assert_unreachable(); - return nullptr; + return {}; } bool try_curves_conversion_in_place(const IndexMask selection, const CurveType dst_type, - FunctionRef<Curves &()> get_writable_curves_fn) + FunctionRef<bke::CurvesGeometry &()> get_writable_curves_fn) { if (conversion_can_change_point_num(dst_type)) { return false; } - Curves &curves_id = get_writable_curves_fn(); - bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + bke::CurvesGeometry &curves = get_writable_curves_fn(); curves.fill_curve_types(selection, dst_type); curves.remove_attributes_based_on_types(); return true; diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index 914174235cd..b6476d19818 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -12,26 +12,6 @@ namespace blender::geometry { /** - * \warning Only the curve domain of the input is copied, so the result is invalid! - */ -static Curves *create_result_curves(const bke::CurvesGeometry &src_curves) -{ - 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. */ - CustomData_copy(&src_curves.curve_data, - &dst_curves.curve_data, - CD_MASK_ALL, - CD_DUPLICATE, - src_curves.curves_num()); - dst_curves.runtime->type_counts = src_curves.runtime->type_counts; - - return dst_curves_id; -} - -/** * Return a range used to retrieve values from an array of values stored per point, but with an * extra element at the end of each curve. This is useful for offsets within curves, where it is * convenient to store the first 0 and have the last offset be the total result curve size. @@ -342,10 +322,9 @@ static void subdivide_bezier_positions(const Span<float3> src_positions, cyclic, dst_types_l, dst_types_r, dst_positions, dst_handles_l, dst_handles_r); } -Curves *subdivide_curves(const CurveComponent &src_component, - const bke::CurvesGeometry &src_curves, - const IndexMask selection, - const VArray<int> &cuts) +bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, + const IndexMask selection, + const VArray<int> &cuts) { const Vector<IndexRange> unselected_ranges = selection.extract_ranges_invert( src_curves.curves_range()); @@ -353,10 +332,7 @@ Curves *subdivide_curves(const CurveComponent &src_component, /* Cyclic is accessed a lot, it's probably worth it to make sure it's a span. */ const VArraySpan<bool> cyclic{src_curves.cyclic()}; - Curves *dst_curves_id = create_result_curves(src_curves); - bke::CurvesGeometry &dst_curves = bke::CurvesGeometry::wrap(dst_curves_id->geometry); - CurveComponent dst_component; - dst_component.replace(dst_curves_id, GeometryOwnershipType::Editable); + bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); /* For each point, this contains the point offset in the corresponding result curve, * starting at zero. For example for two curves with four points each, the values might @@ -385,8 +361,8 @@ Curves *subdivide_curves(const CurveComponent &src_component, dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); - const bke::AttributeAccessor src_attributes = *src_component.attributes(); - bke::MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write(); + const bke::AttributeAccessor src_attributes = src_curves.attributes(); + bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); auto subdivide_catmull_rom = [&](IndexMask selection) { for (auto &attribute : retrieve_point_attributes(src_attributes, dst_attributes)) { @@ -476,7 +452,7 @@ Curves *subdivide_curves(const CurveComponent &src_component, } } - return dst_curves_id; + return dst_curves; } } // namespace blender::geometry |