Cleanup: Avoid adding points to splines sequentially

This should be faster because it avoids reallocating the internal
vectors when the size is known beforehand, but it may also help
a potential refactor to a different data structure (see T94193).
This commit is contained in:
Hans Goudey 2021-12-22 14:35:46 -06:00
parent b4f978e901
commit 0fd72a98ac
Notes: blender-bot 2023-02-14 05:16:25 +01:00
Referenced by commit dbef66c32f, Fix T95952: Uninitialized value used in Bezier Segment node
5 changed files with 45 additions and 44 deletions

View File

@ -79,44 +79,29 @@ static std::unique_ptr<CurveEval> create_bezier_segment_curve(
{
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
std::unique_ptr<BezierSpline> spline = std::make_unique<BezierSpline>();
spline->set_resolution(resolution);
spline->resize(2);
MutableSpan<float3> positions = spline->positions();
spline->handle_types_left().fill(BezierSpline::HandleType::Align);
spline->handle_types_right().fill(BezierSpline::HandleType::Align);
spline->radii().fill(1.0f);
spline->tilts().fill(0.0f);
positions.first() = start;
positions.last() = end;
if (mode == GEO_NODE_CURVE_PRIMITIVE_BEZIER_SEGMENT_POSITION) {
spline->add_point(start,
BezierSpline::HandleType::Align,
2.0f * start - start_handle_right,
BezierSpline::HandleType::Align,
start_handle_right,
1.0f,
0.0f);
spline->add_point(end,
BezierSpline::HandleType::Align,
end_handle_left,
BezierSpline::HandleType::Align,
2.0f * end - end_handle_left,
1.0f,
0.0f);
spline->set_handle_position_right(0, start_handle_right);
spline->set_handle_position_left(1, end_handle_left);
}
else {
spline->add_point(start,
BezierSpline::HandleType::Align,
start - start_handle_right,
BezierSpline::HandleType::Align,
start + start_handle_right,
1.0f,
0.0f);
spline->add_point(end,
BezierSpline::HandleType::Align,
end + end_handle_left,
BezierSpline::HandleType::Align,
end - end_handle_left,
1.0f,
0.0f);
spline->set_handle_position_right(0, start + start_handle_right);
spline->set_handle_position_left(1, end + end_handle_left);
}
spline->set_resolution(resolution);
spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
curve->attributes.reallocate(curve->splines().size());
curve->attributes.reallocate(1);
return curve;
}

View File

@ -50,15 +50,19 @@ static std::unique_ptr<CurveEval> create_quadratic_bezier_curve(const float3 p1,
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
spline->resize(resolution + 1);
MutableSpan<float3> positions = spline->positions();
spline->radii().fill(1.0f);
spline->tilts().fill(0.0f);
const float step = 1.0f / resolution;
for (int i : IndexRange(resolution + 1)) {
for (const int i : IndexRange(resolution + 1)) {
const float factor = step * i;
const float3 q1 = float3::interpolate(p1, p2, factor);
const float3 q2 = float3::interpolate(p2, p3, factor);
const float3 out = float3::interpolate(q1, q2, factor);
spline->add_point(out, 1.0f, 0.0f);
positions[i] = float3::interpolate(q1, q2, factor);
}
spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
curve->attributes.reallocate(curve->splines().size());
return curve;

View File

@ -65,6 +65,11 @@ static std::unique_ptr<CurveEval> create_spiral_curve(const float rotations,
const float delta_theta = (M_PI * 2 * rotations) / (float)totalpoints *
(direction ? 1.0f : -1.0f);
spline->resize(totalpoints + 1);
MutableSpan<float3> positions = spline->positions();
spline->radii().fill(1.0f);
spline->tilts().fill(0.0f);
for (const int i : IndexRange(totalpoints + 1)) {
const float theta = i * delta_theta;
const float radius = start_radius + i * delta_radius;
@ -72,10 +77,9 @@ static std::unique_ptr<CurveEval> create_spiral_curve(const float rotations,
const float y = radius * sin(theta);
const float z = delta_height * i;
spline->add_point(float3(x, y, z), 1.0f, 0.0f);
positions[i] = {x, y, z};
}
spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
curve->attributes.reallocate(curve->splines().size());
return curve;

View File

@ -54,19 +54,24 @@ static std::unique_ptr<CurveEval> create_star_curve(const float inner_radius,
{
std::unique_ptr<CurveEval> curve = std::make_unique<CurveEval>();
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
spline->set_cyclic(true);
spline->resize(points * 2);
MutableSpan<float3> positions = spline->positions();
spline->radii().fill(1.0f);
spline->tilts().fill(0.0f);
const float theta_step = (2.0f * M_PI) / float(points);
for (int i : IndexRange(points)) {
for (const int i : IndexRange(points)) {
const float x = outer_radius * cos(theta_step * i);
const float y = outer_radius * sin(theta_step * i);
spline->add_point(float3(x, y, 0.0f), 1.0f, 0.0f);
positions[i * 2] = {x, y, 0.0f};
const float inner_x = inner_radius * cos(theta_step * i + theta_step * 0.5f + twist);
const float inner_y = inner_radius * sin(theta_step * i + theta_step * 0.5f + twist);
spline->add_point(float3(inner_x, inner_y, 0.0f), 1.0f, 0.0f);
positions[i * 2 + 1] = {inner_x, inner_y, 0.0f};
}
spline->set_cyclic(true);
spline->attributes.reallocate(spline->size());
curve->add_spline(std::move(spline));
curve->attributes.reallocate(curve->splines().size());

View File

@ -81,8 +81,11 @@ static SplinePtr resample_spline(const Spline &src, const int count)
Spline::copy_base_settings(src, *dst);
if (src.evaluated_edges_size() < 1 || count == 1) {
dst->add_point(src.positions().first(), src.radii().first(), src.tilts().first());
dst->attributes.reallocate(1);
dst->resize(1);
dst->positions().first() = src.positions().first();
dst->radii().first() = src.radii().first();
dst->tilts().first() = src.tilts().first();
src.attributes.foreach_attribute(
[&](const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) {
std::optional<GSpan> src_attribute = src.attributes.get_for_read(attribute_id);