Geometry Nodes: Support "Evaluated" mode in Resample Curve node

Just like the curve to points node, this mode outputs point locations
based on the input curve's evaluated points (the points you see in the
viewport). This is expected to be faster, since it doesn't have to
sample equal positions on the result, and it's also consistent with
the existing choices in the curve to points node.
This commit is contained in:
Hans Goudey 2021-09-10 22:58:30 -05:00
parent cb83313863
commit d475f99460
2 changed files with 44 additions and 1 deletions

View File

@ -10091,6 +10091,12 @@ static void def_geo_curve_resample(StructRNA *srna)
PropertyRNA *prop;
static EnumPropertyItem mode_items[] = {
{GEO_NODE_CURVE_SAMPLE_EVALUATED,
"EVALUATED",
0,
"Evaluated",
"Output the input spline's evaluated points, based on the resolution attribute for NURBS "
"and Bezier splines. Poly splines are unchanged"},
{GEO_NODE_CURVE_SAMPLE_COUNT,
"COUNT",
0,

View File

@ -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)
@ -148,6 +148,36 @@ static SplinePtr resample_spline(const Spline &input_spline, const int count)
return output_spline;
}
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 dst;
}
static std::unique_ptr<CurveEval> resample_curve(const CurveEval &input_curve,
const SampleModeParam &mode_param)
{
@ -174,6 +204,13 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveEval &input_curve,
}
});
}
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;