diff options
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.cc | 138 |
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; |