Curves: Avoid calculations in curve to mesh single point case
When the profile is the default (or manually set to a single point at the origin), avoid computing tangents and normals, and avoid evaluating the radius attribute. That data is only used to build the transforms of the new points. In a simple test case, this changed the total time from 34.4 to 14.7 ms (removing the cost 4.7, 8.4, and 2.1 ms) cost of calculating tangents, normals, and radii.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_task.hh"
|
||||
@@ -736,36 +737,39 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
|
||||
sharp_faces.finish();
|
||||
}
|
||||
|
||||
const Span<float3> main_positions = main.evaluated_positions();
|
||||
const Span<float3> tangents = main.evaluated_tangents();
|
||||
const Span<float3> normals = main.evaluated_normals();
|
||||
const Span<float3> profile_positions = profile.evaluated_positions();
|
||||
|
||||
Vector<std::byte> eval_buffer;
|
||||
|
||||
const AttributeAccessor main_attributes = main.attributes();
|
||||
const AttributeAccessor profile_attributes = profile.attributes();
|
||||
|
||||
Span<float> radii = {};
|
||||
if (main_attributes.contains("radius")) {
|
||||
radii = evaluated_attribute_if_necessary(
|
||||
*main_attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 1.0f),
|
||||
main,
|
||||
main.curve_type_counts(),
|
||||
eval_buffer)
|
||||
.typed<float>();
|
||||
const Span<float3> main_positions = main.evaluated_positions();
|
||||
const Span<float3> profile_positions = profile.evaluated_positions();
|
||||
if (profile_positions.size() == 1 && math::is_equal(profile_positions.first(), float3(0.0f))) {
|
||||
array_utils::copy(main_positions, mesh->vert_positions_for_write());
|
||||
}
|
||||
else {
|
||||
const Span<float3> tangents = main.evaluated_tangents();
|
||||
const Span<float3> normals = main.evaluated_normals();
|
||||
Span<float> radii = {};
|
||||
if (main_attributes.contains("radius")) {
|
||||
radii = evaluated_attribute_if_necessary(
|
||||
*main_attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 1.0f),
|
||||
main,
|
||||
main.curve_type_counts(),
|
||||
eval_buffer)
|
||||
.typed<float>();
|
||||
}
|
||||
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
|
||||
fill_mesh_positions(info.main_points.size(),
|
||||
info.profile_points.size(),
|
||||
main_positions.slice(info.main_points),
|
||||
profile_positions.slice(info.profile_points),
|
||||
tangents.slice(info.main_points),
|
||||
normals.slice(info.main_points),
|
||||
radii.is_empty() ? radii : radii.slice(info.main_points),
|
||||
positions.slice(info.vert_range));
|
||||
});
|
||||
}
|
||||
|
||||
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
|
||||
fill_mesh_positions(info.main_points.size(),
|
||||
info.profile_points.size(),
|
||||
main_positions.slice(info.main_points),
|
||||
profile_positions.slice(info.profile_points),
|
||||
tangents.slice(info.main_points),
|
||||
normals.slice(info.main_points),
|
||||
radii.is_empty() ? radii : radii.slice(info.main_points),
|
||||
positions.slice(info.vert_range));
|
||||
});
|
||||
|
||||
if (!offsets.any_single_point_main) {
|
||||
/* If there are no single point curves, every combination will have at least loose edges. */
|
||||
@@ -882,7 +886,7 @@ static CurvesGeometry get_curve_single_vert()
|
||||
{
|
||||
CurvesGeometry curves(1, 1);
|
||||
curves.offsets_for_write().last() = 1;
|
||||
curves.positions_for_write().fill(float3(0));
|
||||
curves.positions_for_write().fill(float3(0.0f));
|
||||
curves.fill_curve_types(CURVE_TYPE_POLY);
|
||||
|
||||
return curves;
|
||||
|
||||
Reference in New Issue
Block a user