[Bf-blender-cvs] [837d630466b] geometry-nodes-curve-support: Splines: Halve the size of the bezier interpolation cache
Hans Goudey
noreply at git.blender.org
Sat Apr 24 22:02:13 CEST 2021
Commit: 837d630466bfb1a15b2947987ed65a04de211cda
Author: Hans Goudey
Date: Sat Apr 24 15:01:32 2021 -0500
Branches: geometry-nodes-curve-support
https://developer.blender.org/rB837d630466bfb1a15b2947987ed65a04de211cda
Splines: Halve the size of the bezier interpolation cache
Use floats to store the control point indices and the interpolation factors.
===================================================================
M source/blender/blenkernel/BKE_spline.hh
M source/blender/blenkernel/intern/spline_bezier.cc
M source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
M source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_spline.hh b/source/blender/blenkernel/BKE_spline.hh
index 21249de57f2..78f0c33861f 100644
--- a/source/blender/blenkernel/BKE_spline.hh
+++ b/source/blender/blenkernel/BKE_spline.hh
@@ -32,23 +32,6 @@
struct Curve;
-/**
- * Contains the information necessary to interpolate values from the original control points to
- * evaluated points.
- */
-struct PointMapping {
- /**
- * The index of the control point preceding the evaluated point at this index.
- * For resolutions higher than 1, many evaluated points can share the same value.
- */
- int control_point_index;
- /**
- * This evaluated point's portion of the total length between the `control_point_index` value
- * and the next.
- */
- float factor;
-};
-
class Spline;
using SplinePtr = std::unique_ptr<Spline>;
@@ -190,7 +173,7 @@ class BezierSpline final : public Spline {
mutable bool base_cache_dirty_ = true;
mutable std::mutex base_cache_mutex_;
mutable blender::Vector<blender::float3> evaluated_positions_cache_;
- mutable blender::Vector<PointMapping> evaluated_mappings_cache_;
+ mutable blender::Vector<float> evaluated_mappings_cache_;
public:
virtual SplinePtr copy() const final;
@@ -253,7 +236,7 @@ class BezierSpline final : public Spline {
void mark_cache_invalid() final;
int evaluated_points_size() const final;
- blender::Span<PointMapping> evaluated_mappings() const;
+ blender::Span<float> evaluated_mappings() const;
blender::Span<blender::float3> evaluated_positions() const final;
virtual blender::fn::GVArrayPtr interpolate_to_evaluated_points(
@@ -269,7 +252,7 @@ class BezierSpline final : public Spline {
const int next_index,
int &offset,
blender::MutableSpan<blender::float3> positions,
- blender::MutableSpan<PointMapping> mappings) const;
+ blender::MutableSpan<float> mappings) const;
void evaluate_bezier_position_and_mapping() const;
};
diff --git a/source/blender/blenkernel/intern/spline_bezier.cc b/source/blender/blenkernel/intern/spline_bezier.cc
index e7d59d830dc..c065f8f68cc 100644
--- a/source/blender/blenkernel/intern/spline_bezier.cc
+++ b/source/blender/blenkernel/intern/spline_bezier.cc
@@ -296,21 +296,21 @@ static void bezier_forward_difference_3d(const float3 &point_0,
}
static void evaluate_segment_mapping(Span<float3> evaluated_positions,
- MutableSpan<PointMapping> mappings,
+ MutableSpan<float> mappings,
const int index)
{
float length = 0.0f;
- mappings[0] = PointMapping{index, 0.0f};
+ mappings[0] = index;
for (const int i : IndexRange(1, mappings.size() - 1)) {
length += float3::distance(evaluated_positions[i - 1], evaluated_positions[i]);
- mappings[i] = PointMapping{index, length};
+ mappings[i] = length;
}
/* To get the factors instead of the accumulated lengths, divide the mapping factors by the
* accumulated length. */
if (length != 0.0f) {
- for (PointMapping &mapping : mappings) {
- mapping.factor /= length;
+ for (float &mapping : mappings) {
+ mapping = mapping / length + index;
}
}
}
@@ -319,11 +319,11 @@ void BezierSpline::evaluate_bezier_segment(const int index,
const int next_index,
int &offset,
MutableSpan<float3> positions,
- MutableSpan<PointMapping> mappings) const
+ MutableSpan<float> mappings) const
{
if (this->segment_is_vector(index)) {
positions[offset] = positions_[index];
- mappings[offset] = PointMapping{index, 0.0f};
+ mappings[offset] = index;
offset++;
}
else {
@@ -355,7 +355,7 @@ void BezierSpline::evaluate_bezier_position_and_mapping() const
this->evaluated_mappings_cache_.resize(total);
MutableSpan<float3> positions = this->evaluated_positions_cache_;
- MutableSpan<PointMapping> mappings = this->evaluated_mappings_cache_;
+ MutableSpan<float> mappings = this->evaluated_mappings_cache_;
/* TODO: It would also be possible to store an array of offsets to facilitate parallelism here,
* maybe it is worth it? */
@@ -372,50 +372,51 @@ void BezierSpline::evaluate_bezier_position_and_mapping() const
/* Since evaulating the bezier doesn't add the final point's position,
* it must be added manually in the non-cyclic case. */
positions[offset] = this->positions_.last();
- mappings[offset] = PointMapping{i_last - 1, 1.0f};
+ mappings[offset] = i_last;
offset++;
}
+ if (this->is_cyclic) {
+ if (mappings.last() >= this->size()) {
+ mappings.last() = 0.0f;
+ }
+ }
+
BLI_assert(offset == positions.size());
this->base_cache_dirty_ = false;
}
/**
- * Returns non-owning access to the cache of mappings from the evaluated points to
- * the corresponing control points. Unless the spline is cyclic, the last control point
- * index will never be included as an index.
+ * Returns non-owning access to an array of values ontains the information necessary to
+ * interpolate values from the original control points to evaluated points. The control point
+ * index is the integer part of each value, and the factor used for interpolating to the next
+ * control point is the remaining factional part.
*/
-Span<PointMapping> BezierSpline::evaluated_mappings() const
+Span<float> BezierSpline::evaluated_mappings() const
{
this->evaluate_bezier_position_and_mapping();
-#ifdef DEBUG
- if (evaluated_mappings_cache_.last().control_point_index == this->size() - 1) {
- BLI_assert(this->is_cyclic);
- }
-#endif
return this->evaluated_mappings_cache_;
}
Span<float3> BezierSpline::evaluated_positions() const
{
this->evaluate_bezier_position_and_mapping();
-
return this->evaluated_positions_cache_;
}
template<typename T>
-static void interpolate_to_evaluated_points_impl(Span<PointMapping> mappings,
+static void interpolate_to_evaluated_points_impl(Span<float> mappings,
const blender::VArray<T> &source_data,
MutableSpan<T> result_data)
{
+ const int points_len = source_data.size();
blender::attribute_math::DefaultMixer<T> mixer(result_data);
for (const int i : result_data.index_range()) {
- const PointMapping &mapping = mappings[i];
- const int index = mapping.control_point_index;
- const int next_index = (index + 1) % source_data.size();
- const float factor = mapping.factor;
+ const int index = std::floor(mappings[i]);
+ const int next_index = (index == points_len - 1) ? 0 : index + 1;
+ const float factor = mappings[i] - index;
const T &value = source_data[index];
const T &next_value = source_data[next_index];
@@ -431,7 +432,7 @@ blender::fn::GVArrayPtr BezierSpline::interpolate_to_evaluated_points(
const blender::fn::GVArray &source_data) const
{
BLI_assert(source_data.size() == this->size());
- Span<PointMapping> mappings = this->evaluated_mappings();
+ Span<float> mappings = this->evaluated_mappings();
blender::fn::GVArrayPtr new_varray;
blender::attribute_math::convert_to_static_type(source_data.type(), [&](auto dummy) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
index dad5c579a3b..21995295898 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
@@ -59,6 +59,22 @@ static void vert_extrude_to_mesh_data(const Spline &spline,
edge.v2 = vert_offset + i + 1;
edge.flag = ME_LOOSEEDGE;
}
+ // for (const int i : IndexRange(positions.size() - 1)) {
+ // MEdge &edge = edges[edge_offset++];
+ // edge.v1 = vert_offset + i * 3;
+ // edge.v2 = vert_offset + i * 3 + 3;
+ // edge.flag = ME_LOOSEEDGE;
+
+ // MEdge &tangent_edge = edges[edge_offset++];
+ // tangent_edge.v1 = vert_offset + i * 3;
+ // tangent_edge.v2 = vert_offset + i * 3 + 1;
+ // tangent_edge.flag = ME_LOOSEEDGE;
+
+ // MEdge &normal_edge = edges[edge_offset++];
+ // normal_edge.v1 = vert_offset + i * 3;
+ // normal_edge.v2 = vert_offset + i * 3 + 2;
+ // normal_edge.flag = ME_LOOSEEDGE;
+ // }
if (spline.is_cyclic) {
MEdge &edge = edges[edge_offset++];
@@ -71,6 +87,18 @@ static void vert_extrude_to_mesh_data(const Spline &spline,
MVert &vert = verts[vert_offset++];
copy_v3_v3(vert.co, positions[i] + profile_vert);
}
+ // Span<float3> tangents = spline.evaluated_tangents();
+ // Span<float3> normals = spline.evaluated_normals();
+ // for (const int i : positions.index_range()) {
+ // MVert &vert = verts[vert_offset++];
+ // copy_v3_v3(vert.co, positions[i] + profile_vert);
+
+ // MVert &tangent_vert = verts[vert_offset++];
+ // copy_v3_v3(tangent_vert.co, tangents[i] + vert.co);
+
+ // MVert &normal_vert = verts[vert_offset++];
+ // copy_v3_v3(normal_vert.co, normals[i] + vert.co);
+ // }
}
static void mark_edges_sharp(MutableSpan<MEdge> edges)
@@ -202,11 +230,11 @@ static void spline_extrude_to_mesh_data(const Spline &spline,
/* Mark edge loops from sharp vector control points sharp. */
if (profile_spline.type() == Spline::Bezier) {
const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(profile_spline);
- Span<PointMapping> mappings = bezier_spline.evaluated_mappings();
+ Span<float> mappings = bezier_spline.evaluated_mappings();
for (const int i_profile : mappings.index_range()) {
- const PointMapping &mapping = mappings[i_profile];
- if (mapping.factor == 0.0f) {
- if (bezier_spline.point_is_sharp(mapping.control_point_index)) {
+ const float index = std::floor(mappings[i_profile]);
+ if ((mappings[i_profile] - index) == 0.0f) {
+ if (bezier
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list