[Bf-blender-cvs] [93e0559f54c] microfacet_hair: WIP: calculate normals aligned with the curvature vector Only works for Catmull-Rom and poly curve types for now
Weizhen Huang
noreply at git.blender.org
Mon Jan 2 15:50:54 CET 2023
Commit: 93e0559f54c087a64121b4b30708be096a3d7c3e
Author: Weizhen Huang
Date: Mon Jan 2 15:49:28 2023 +0100
Branches: microfacet_hair
https://developer.blender.org/rB93e0559f54c087a64121b4b30708be096a3d7c3e
WIP: calculate normals aligned with the curvature vector
Only works for Catmull-Rom and poly curve types for now
===================================================================
M release/datafiles/locale
M release/scripts/addons
M release/scripts/addons_contrib
M source/blender/blenkernel/BKE_curves.hh
M source/blender/blenkernel/intern/curve_catmull_rom.cc
M source/blender/blenkernel/intern/curve_legacy_convert.cc
M source/blender/blenkernel/intern/curve_poly.cc
M source/blender/blenkernel/intern/curves_geometry.cc
M source/blender/blenkernel/intern/geometry_component_curves.cc
M source/blender/geometry/intern/add_curves_on_mesh.cc
M source/blender/geometry/intern/trim_curves.cc
M source/blender/makesdna/DNA_curves_types.h
M source/blender/makesrna/intern/rna_curves.c
M source/tools
===================================================================
diff --git a/release/datafiles/locale b/release/datafiles/locale
index e398d3c4969..7084c4ecd97 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit e398d3c4969a37ae2ecff388344dd780bc1cfe82
+Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df
diff --git a/release/scripts/addons b/release/scripts/addons
index 90c87dd771e..042c799b7ae 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 90c87dd771e027e0ffa157a0e294399bfd605d99
+Subproject commit 042c799b7aef9634a33d24e78d4922706aca9a2b
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
index 96143b1a8b0..bdcfdd47ec3 160000
--- a/release/scripts/addons_contrib
+++ b/release/scripts/addons_contrib
@@ -1 +1 @@
-Subproject commit 96143b1a8b037ea3c81f065f557025db9fe1ace3
+Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index 9382a912c02..44d0dd132aa 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -520,6 +520,13 @@ void calculate_tangents(Span<float3> positions, bool is_cyclic, MutableSpan<floa
*/
void calculate_normals_minimum(Span<float3> tangents, bool cyclic, MutableSpan<float3> normals);
+/**
+ * Calculate curvature vectors. TODO: more description. */
+void calculate_curvature_vectors(Span<float3> positions,
+ Span<float3> tangents,
+ bool cyclic,
+ MutableSpan<float3> normals);
+
/**
* Calculate a vector perpendicular to every tangent on the X-Y plane (unless the tangent is
* vertical, in that case use the X direction).
@@ -696,6 +703,16 @@ void interpolate_to_evaluated(GSpan src, Span<int> evaluated_offsets, GMutableSp
namespace catmull_rom {
+void calculate_tangents(Span<float3> positions,
+ bool is_cyclic,
+ int resolution,
+ MutableSpan<float3> tangents);
+void calculate_normals(Span<float3> positions,
+ bool is_cyclic,
+ int resolution,
+ Span<float3> tangents,
+ MutableSpan<float3> normals);
+
/**
* Calculate the number of evaluated points that #interpolate_to_evaluated is expected to produce.
* \param points_num: The number of points in the curve.
@@ -719,6 +736,8 @@ void interpolate_to_evaluated(const GSpan src,
GMutableSpan dst);
void calculate_basis(const float parameter, float4 &r_weights);
+void calculate_basis_derivative(const float parameter, float4 &r_weights);
+void calculate_basis_derivative2(const float parameter, float4 &r_weights);
/**
* Interpolate the control point values for the given parameter on the piecewise segment.
@@ -727,11 +746,24 @@ void calculate_basis(const float parameter, float4 &r_weights);
* \param parameter: Parameter in range [0, 1] to compute the interpolation for.
*/
template<typename T>
-T interpolate(const T &a, const T &b, const T &c, const T &d, const float parameter)
+T interpolate(
+ const int order, const T &a, const T &b, const T &c, const T &d, const float parameter)
{
BLI_assert(0.0f <= parameter && parameter <= 1.0f);
float4 n;
- calculate_basis(parameter, n);
+
+ switch (order) {
+ case 1:
+ calculate_basis_derivative(parameter, n);
+ break;
+ case 2:
+ calculate_basis_derivative2(parameter, n);
+ break;
+ default:
+ calculate_basis(parameter, n);
+ break;
+ }
+
if constexpr (is_same_any_v<T, float, float2, float3>) {
/* Save multiplications by adjusting weights after mix. */
return 0.5f * attribute_math::mix4<T>(n, a, b, c, d);
diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc
index 8247d9451e4..7bd5db488f4 100644
--- a/source/blender/blenkernel/intern/curve_catmull_rom.cc
+++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc
@@ -31,13 +31,37 @@ void calculate_basis(const float parameter, float4 &r_weights)
r_weights[3] = -s * t * t;
}
+/* Adapted from Cycles #catmull_rom_basis_derivative function. */
+void calculate_basis_derivative(const float parameter, float4 &r_weights)
+{
+ const float t = parameter;
+ const float s = 1.0f - parameter;
+ r_weights[0] = s * (2.0f * t - s);
+ r_weights[1] = t * (9.0f * t - 10.0f);
+ r_weights[2] = -s * (9.0f * s - 10.0f);
+ r_weights[3] = t * (t - 2.0f * s);
+}
+
+/* Adapted from Cycles #catmull_rom_basis_derivative2 function. */
+void calculate_basis_derivative2(const float parameter, float4 &r_weights)
+{
+ const float t = parameter;
+ const float s = 1.0f - parameter;
+ r_weights[0] = -6.0f * t + 4.0f;
+ r_weights[1] = 18.0f * t - 10.0f;
+ r_weights[2] = 18.0f * s - 10.0f;
+ r_weights[3] = 6.0f * t - 2.0f;
+}
+
template<typename T>
-static void evaluate_segment(const T &a, const T &b, const T &c, const T &d, MutableSpan<T> dst)
+static void evaluate_segment(
+ const int order, const T &a, const T &b, const T &c, const T &d, MutableSpan<T> dst)
{
const float step = 1.0f / dst.size();
dst.first() = b;
- for (const int i : dst.index_range().drop_front(1)) {
- dst[i] = interpolate<T>(a, b, c, d, i * step);
+ IndexRange index_range = (order == 0) ? dst.index_range().drop_front(1) : dst.index_range();
+ for (const int i : index_range) {
+ dst[i] = interpolate(order, a, b, c, d, i * step);
}
}
@@ -45,9 +69,11 @@ static void evaluate_segment(const T &a, const T &b, const T &c, const T &d, Mut
* \param range_fn: Returns an index range describing where in the #dst span each segment should be
* evaluated to, and how many points to add to it. This is used to avoid the need to allocate an
* actual offsets array in typical evaluation use cases where the resolution is per-curve.
+ * \param order: The order of the derivative. order == 0 is the default.
*/
template<typename T, typename RangeForSegmentFn>
-static void interpolate_to_evaluated(const Span<T> src,
+static void interpolate_to_evaluated(const int order,
+ const Span<T> src,
const bool cyclic,
const RangeForSegmentFn &range_fn,
MutableSpan<T> dst)
@@ -59,20 +85,30 @@ static void interpolate_to_evaluated(const Span<T> src,
* - Finally evaluate all of the segments in the middle in parallel. */
if (src.size() == 1) {
- dst.first() = src.first();
+ switch (order) {
+ case 1:
+ dst.first() = float3(0.0f, 0.0f, 1.0f);
+ break;
+ case 2:
+ dst.first() = float3(1.0f, 0.0f, 0.0f);
+ break;
+ default:
+ dst.first() = src.first();
+ break;
+ }
return;
}
const IndexRange first = range_fn(0);
if (src.size() == 2) {
- evaluate_segment(src.first(), src.first(), src.last(), src.last(), dst.slice(first));
+ evaluate_segment(order, src.first(), src.first(), src.last(), src.last(), dst.slice(first));
if (cyclic) {
const IndexRange last = range_fn(1);
- evaluate_segment(src.last(), src.last(), src.first(), src.first(), dst.slice(last));
+ evaluate_segment(order, src.last(), src.last(), src.first(), src.first(), dst.slice(last));
}
else {
- dst.last() = src.last();
+ dst.last() = interpolate(order, src.first(), src.first(), src.last(), src.last(), 1);
}
return;
}
@@ -80,17 +116,19 @@ static void interpolate_to_evaluated(const Span<T> src,
const IndexRange second_to_last = range_fn(src.index_range().last(1));
const IndexRange last = range_fn(src.index_range().last());
if (cyclic) {
- evaluate_segment(src.last(), src[0], src[1], src[2], dst.slice(first));
- evaluate_segment(src.last(2), src.last(1), src.last(), src.first(), dst.slice(second_to_last));
- evaluate_segment(src.last(1), src.last(), src[0], src[1], dst.slice(last));
+ evaluate_segment(order, src.last(), src[0], src[1], src[2], dst.slice(first));
+ evaluate_segment(
+ order, src.last(2), src.last(1), src.last(), src.first(), dst.slice(second_to_last));
+ evaluate_segment(order, src.last(1), src.last(), src[0], src[1], dst.slice(last));
}
else {
- evaluate_segment(src[0], src[0], src[1], src[2], dst.slice(first));
- evaluate_segment(src.last(2), src.last(1), src.last(), src.last(), dst.slice(second_to_last));
+ evaluate_segment(order, src[0], src[0], src[1], src[2], dst.slice(first));
+ evaluate_segment(
+ order, src.last(2), src.last(1), src.last(), src.last(), dst.slice(second_to_last));
/* For non-cyclic curves, the last segment should always just have a single point. We could
* assert that the size of the provided range is 1 here, but that would require specializing
* the #range_fn implementation for the last point, which may have a performance cost. */
- dst.last() = src.last();
+ dst.last() = interpolate(order, src.last(2), src.last(1), src.last(), src.last(), 1);
}
/* Evaluate every segment that isn't the first or last. */
@@ -98,7 +136,7 @@ static void interpolate_to_evaluated(const Span<T> src,
threading::parallel_for(inner_range, 512, [&](IndexRange range) {
for (const int i : range) {
const IndexRange segment = range_fn(i);
- evaluate_segment(src[i - 1], src[i], src[i + 1], src[i + 2], dst.slice(segment));
+ evaluate_segment(order, src[i - 1], src[i], src[i + 1], src[i + 2], dst.slice(segment));
}
});
}
@@ -112,6 +150,7 @@ static void interpolate_to_evaluated(const Span<T> src,
{
BLI_assert(dst.size() == calculate_evaluated_num(src.size(), cyclic, resolution));
interpolate_to_evaluated(
+ 0,
src,
cyclic,
[resolution](const int segment_i) -> IndexRange {
@@ -128,6 +167,7 @@ static void interpolate_to_evaluated(const Span<T> src,
{
interpolate_to_evaluated(
+ 0,
src,
cyclic,
[evaluated_offsets](const int segment_i) -> IndexRange {
@@ -158,4 +198,76
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list