18 const float epsilon = 1.0e-9f;
25 r_delta_dir = delta /
norm;
38 const float epsilon = 1.0e-9f;
39 const bool prev_equal = is_equal;
43 is_equal = next_norm < epsilon;
51 const float3 prev_dir = other_dir;
52 other_dir = next_delta / next_norm;
58 const float3 tangent = prev_dir + other_dir;
60 if (
norm < 0.6627619f) {
68 const float3 normal = other_dir - prev_dir;
71 return tangent /
norm;
84 if (positions.
size() == 1) {
90 int first_valid_index = -1;
92 if (
delta_dir(positions[
i], positions[
i + 1], tangents[
i])) {
93 first_valid_index =
i;
98 if (first_valid_index == -1) {
101 const float3 up_vector{0.0f, 0.0f, 1.0f};
102 tangents.
fill(up_vector);
105 if (first_valid_index > 0) {
106 tangents.
slice(0, first_valid_index).
fill(tangents[first_valid_index]);
110 float3 prev_delta = tangents[first_valid_index];
111 bool prev_equal =
false;
122 tangents.
last() = prev_delta;
131 const float epsilon = 1e-4f;
132 for (
const int i :
normals.index_range()) {
133 const float3 &tangent = tangents[
i];
134 if (std::abs(tangent.x) + std::abs(tangent.y) < epsilon) {
147 const float3 &last_tangent,
148 const float3 ¤t_tangent)
176 const float epsilon = 1e-4f;
181 normals.first() = {1.0f, 0.0f, 0.0f};
201 normals.first(), uncorrected_last_normal, tangents.
first());
202 if (correction_angle >
M_PI) {
203 correction_angle = correction_angle - 2 *
M_PI;
207 const float angle_step = correction_angle /
normals.size();
208 for (
const int i :
normals.index_range()) {
209 const float3 axis = tangents[
i];
213 const float angle = angle_step *
i;
Low-level operations for curves.
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
constexpr IndexRange drop_back(int64_t n) const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr void fill(const T &value) const
constexpr T & first() const
constexpr T & last(const int64_t n=0) const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
static bool is_cyclic(const Nurb *nu)
static float normals[][3]
ccl_device_inline float2 fabs(const float2 a)
void calculate_normals_z_up(Span< float3 > tangents, MutableSpan< float3 > normals)
static bool delta_dir(const float3 &pos, const float3 &next, float3 &r_delta_dir)
static float3 direction_bisect(const float3 &pos, const float3 &next, float3 &other_dir, bool &is_equal)
void calculate_normals_minimum(Span< float3 > tangents, bool cyclic, MutableSpan< float3 > normals)
static float3 calculate_next_normal(const float3 &last_normal, const float3 &last_tangent, const float3 ¤t_tangent)
void calculate_tangents(Span< float3 > positions, bool is_cyclic, MutableSpan< float3 > tangents)
T length(const VecBase< T, Size > &a)
float3 rotate_direction_around_axis(const float3 &direction, const float3 &axis, float angle)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< float, 3 > float3