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:
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc138
1 files changed, 80 insertions, 58 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
index 0b71a8cb03a..e89d500fe57 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc
@@ -42,7 +42,7 @@ static void geo_node_curve_resample_declare(NodeDeclarationBuilder &b)
static void geo_node_curve_resample_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void geo_node_curve_resample_init(bNodeTree *UNUSED(tree), bNode *node)
@@ -72,80 +72,95 @@ struct SampleModeParam {
std::optional<int> count;
};
-static SplinePtr resample_spline(const Spline &input_spline, const int count)
+static SplinePtr resample_spline(const Spline &src, const int count)
{
- std::unique_ptr<PolySpline> output_spline = std::make_unique<PolySpline>();
- output_spline->set_cyclic(input_spline.is_cyclic());
- output_spline->normal_mode = input_spline.normal_mode;
-
- if (input_spline.evaluated_edges_size() < 1 || count == 1) {
- output_spline->add_point(input_spline.positions().first(),
- input_spline.tilts().first(),
- input_spline.radii().first());
- output_spline->attributes.reallocate(1);
- input_spline.attributes.foreach_attribute(
- [&](StringRefNull name, const AttributeMetaData &meta_data) {
- std::optional<GSpan> src = input_spline.attributes.get_for_read(name);
- BLI_assert(src);
- if (!output_spline->attributes.create(name, meta_data.data_type)) {
- BLI_assert_unreachable();
- return false;
+ std::unique_ptr<PolySpline> dst = std::make_unique<PolySpline>();
+ Spline::copy_base_settings(src, *dst);
+
+ if (src.evaluated_edges_size() < 1 || count == 1) {
+ dst->add_point(src.positions().first(), src.tilts().first(), src.radii().first());
+ dst->attributes.reallocate(1);
+ src.attributes.foreach_attribute(
+ [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
+ std::optional<GSpan> src_attribute = src.attributes.get_for_read(attribute_id);
+ if (dst->attributes.create(attribute_id, meta_data.data_type)) {
+ std::optional<GMutableSpan> dst_attribute = dst->attributes.get_for_write(
+ attribute_id);
+ if (dst_attribute) {
+ src_attribute->type().copy_assign(src_attribute->data(), dst_attribute->data());
+ return true;
+ }
}
- std::optional<GMutableSpan> dst = output_spline->attributes.get_for_write(name);
- if (!dst) {
- BLI_assert_unreachable();
- return false;
- }
- src->type().copy_assign(src->data(), dst->data());
- return true;
+ BLI_assert_unreachable();
+ return false;
},
ATTR_DOMAIN_POINT);
- return output_spline;
+ return dst;
}
- output_spline->resize(count);
+ dst->resize(count);
- Array<float> uniform_samples = input_spline.sample_uniform_index_factors(count);
+ Array<float> uniform_samples = src.sample_uniform_index_factors(count);
- input_spline.sample_with_index_factors<float3>(
- input_spline.evaluated_positions(), uniform_samples, output_spline->positions());
+ src.sample_with_index_factors<float3>(
+ src.evaluated_positions(), uniform_samples, dst->positions());
- input_spline.sample_with_index_factors<float>(
- input_spline.interpolate_to_evaluated(input_spline.radii()),
- uniform_samples,
- output_spline->radii());
+ src.sample_with_index_factors<float>(
+ src.interpolate_to_evaluated(src.radii()), uniform_samples, dst->radii());
- input_spline.sample_with_index_factors<float>(
- input_spline.interpolate_to_evaluated(input_spline.tilts()),
- uniform_samples,
- output_spline->tilts());
+ src.sample_with_index_factors<float>(
+ src.interpolate_to_evaluated(src.tilts()), uniform_samples, dst->tilts());
- output_spline->attributes.reallocate(count);
- input_spline.attributes.foreach_attribute(
- [&](StringRefNull name, const AttributeMetaData &meta_data) {
- std::optional<GSpan> input_attribute = input_spline.attributes.get_for_read(name);
- BLI_assert(input_attribute);
- if (!output_spline->attributes.create(name, meta_data.data_type)) {
- BLI_assert_unreachable();
- return false;
- }
- std::optional<GMutableSpan> output_attribute = output_spline->attributes.get_for_write(
- name);
- if (!output_attribute) {
- BLI_assert_unreachable();
- return false;
+ src.attributes.foreach_attribute(
+ [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
+ std::optional<GSpan> input_attribute = src.attributes.get_for_read(attribute_id);
+ if (dst->attributes.create(attribute_id, meta_data.data_type)) {
+ std::optional<GMutableSpan> output_attribute = dst->attributes.get_for_write(
+ attribute_id);
+ if (output_attribute) {
+ src.sample_with_index_factors(*src.interpolate_to_evaluated(*input_attribute),
+ uniform_samples,
+ *output_attribute);
+ return true;
+ }
}
- input_spline.sample_with_index_factors(
- *input_spline.interpolate_to_evaluated(*input_attribute),
- uniform_samples,
- *output_attribute);
+ BLI_assert_unreachable();
+ return false;
+ },
+ ATTR_DOMAIN_POINT);
+
+ return dst;
+}
+
+static SplinePtr resample_spline_evaluated(const Spline &src)
+{
+ std::unique_ptr<PolySpline> dst = std::make_unique<PolySpline>();
+ Spline::copy_base_settings(src, *dst);
+ dst->resize(src.evaluated_points_size());
+
+ dst->positions().copy_from(src.evaluated_positions());
+ dst->positions().copy_from(src.evaluated_positions());
+ src.interpolate_to_evaluated(src.radii())->materialize(dst->radii());
+ src.interpolate_to_evaluated(src.tilts())->materialize(dst->tilts());
+
+ src.attributes.foreach_attribute(
+ [&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
+ std::optional<GSpan> src_attribute = src.attributes.get_for_read(attribute_id);
+ if (dst->attributes.create(attribute_id, meta_data.data_type)) {
+ std::optional<GMutableSpan> dst_attribute = dst->attributes.get_for_write(attribute_id);
+ if (dst_attribute) {
+ src.interpolate_to_evaluated(*src_attribute)->materialize(dst_attribute->data());
+ return true;
+ }
+ }
+ BLI_assert_unreachable();
return true;
},
ATTR_DOMAIN_POINT);
- return output_spline;
+ return dst;
}
static std::unique_ptr<CurveEval> resample_curve(const CurveEval &input_curve,
@@ -169,11 +184,18 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveEval &input_curve,
threading::parallel_for(input_splines.index_range(), 128, [&](IndexRange range) {
for (const int i : range) {
const float length = input_splines[i]->length();
- const int count = std::max(int(length / *mode_param.length), 1);
+ const int count = std::max(int(length / *mode_param.length) + 1, 1);
output_splines[i] = resample_spline(*input_splines[i], count);
}
});
}
+ else if (mode_param.mode == GEO_NODE_CURVE_SAMPLE_EVALUATED) {
+ threading::parallel_for(input_splines.index_range(), 128, [&](IndexRange range) {
+ for (const int i : range) {
+ output_splines[i] = resample_spline_evaluated(*input_splines[i]);
+ }
+ });
+ }
output_curve->attributes = input_curve.attributes;