Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-07-19 18:14:46 +0300
committerHans Goudey <h.goudey@me.com>2022-07-19 18:16:30 +0300
commit6a1ab4747b7758017721cb191046a9db800f7894 (patch)
treea3e28d26c96c2070b231bcb6c5f6a9b0409361aa /source/blender/geometry
parent9246ff373a19df24255d924979c78793f97b2834 (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')
-rw-r--r--source/blender/geometry/GEO_mesh_to_curve.hh12
-rw-r--r--source/blender/geometry/GEO_set_curve_type.hh18
-rw-r--r--source/blender/geometry/GEO_subdivide_curves.hh10
-rw-r--r--source/blender/geometry/intern/mesh_to_curve_convert.cc23
-rw-r--r--source/blender/geometry/intern/realize_instances.cc5
-rw-r--r--source/blender/geometry/intern/set_curve_type.cc76
-rw-r--r--source/blender/geometry/intern/subdivide_curves.cc38
7 files changed, 61 insertions, 121 deletions
diff --git a/source/blender/geometry/GEO_mesh_to_curve.hh b/source/blender/geometry/GEO_mesh_to_curve.hh
index c480e4178cf..f619aaff217 100644
--- a/source/blender/geometry/GEO_mesh_to_curve.hh
+++ b/source/blender/geometry/GEO_mesh_to_curve.hh
@@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#pragma once
+
#include "BLI_index_mask.hh"
-#pragma once
+#include "BKE_curves.hh"
struct Mesh;
-struct Curves;
-class MeshComponent;
/** \file
* \ingroup geo
@@ -15,10 +15,10 @@ class MeshComponent;
namespace blender::geometry {
/**
- * Convert the mesh into one or many poly splines. Since splines cannot have branches,
- * intersections of more than three edges will become breaks in splines. Attributes that
+ * Convert the mesh into one or many poly curves. Since curves cannot have branches,
+ * intersections of more than three edges will become breaks in curves. Attributes that
* are not built-in on meshes and not curves are transferred to the result curve.
*/
-Curves *mesh_to_curve_convert(const MeshComponent &mesh_component, const IndexMask selection);
+bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh, const IndexMask selection);
} // namespace blender::geometry
diff --git a/source/blender/geometry/GEO_set_curve_type.hh b/source/blender/geometry/GEO_set_curve_type.hh
index 6a75450006b..f38e63b1fc8 100644
--- a/source/blender/geometry/GEO_set_curve_type.hh
+++ b/source/blender/geometry/GEO_set_curve_type.hh
@@ -2,17 +2,10 @@
#pragma once
-#include "DNA_curves_types.h"
-
#include "BLI_function_ref.hh"
#include "BLI_index_mask.hh"
-struct Curves;
-class CurveComponent;
-
-namespace blender::bke {
-class CurvesGeometry;
-}
+#include "BKE_curves.hh"
namespace blender::geometry {
@@ -27,14 +20,13 @@ namespace blender::geometry {
*/
bool try_curves_conversion_in_place(IndexMask selection,
CurveType dst_type,
- FunctionRef<Curves &()> get_writable_curves_fn);
+ FunctionRef<bke::CurvesGeometry &()> 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);
+bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves,
+ IndexMask selection,
+ CurveType dst_type);
} // namespace blender::geometry
diff --git a/source/blender/geometry/GEO_subdivide_curves.hh b/source/blender/geometry/GEO_subdivide_curves.hh
index 66c2eb53496..ba55118baa4 100644
--- a/source/blender/geometry/GEO_subdivide_curves.hh
+++ b/source/blender/geometry/GEO_subdivide_curves.hh
@@ -4,11 +4,10 @@
#include "BLI_function_ref.hh"
#include "BLI_index_mask.hh"
+#include "BLI_virtual_array.hh"
#include "BKE_curves.hh"
-class CurveComponent;
-
namespace blender::geometry {
/**
@@ -18,9 +17,8 @@ namespace blender::geometry {
*
* \param selection: A selection of curves to consider when subdividing.
*/
-Curves *subdivide_curves(const CurveComponent &src_component,
- const bke::CurvesGeometry &src_curves,
- IndexMask selection,
- const VArray<int> &cuts);
+bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves,
+ IndexMask selection,
+ const VArray<int> &cuts);
} // namespace blender::geometry
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