18 const float epsilon = 1e-6f;
35 const float epsilon = 1e-6f;
36 const bool prev_equal = is_equal;
45 const float3 prev_dir = other_dir;
64 if (positions.
size() == 1) {
70 int first_valid_index = -1;
72 if (
delta_dir(positions[
i], positions[
i + 1], tangents[
i])) {
73 first_valid_index =
i;
78 if (first_valid_index == -1) {
81 const float3 up_vector{0.0f, 0.0f, 1.0f};
82 tangents.
fill(up_vector);
85 if (first_valid_index > 0) {
86 tangents.
slice(0, first_valid_index).
fill(tangents[first_valid_index]);
90 float3 prev_delta = tangents[first_valid_index];
91 bool prev_equal =
false;
102 tangents.
last() = prev_delta;
111 const float epsilon = 1e-4f;
112 for (
const int i :
normals.index_range()) {
113 const float3 &tangent = tangents[
i];
114 if (std::abs(tangent.x) + std::abs(tangent.y) < epsilon) {
127 const float3 &last_tangent,
128 const float3 ¤t_tangent)
156 const float epsilon = 1e-4f;
161 normals.first() = {1.0f, 0.0f, 0.0f};
181 normals.first(), uncorrected_last_normal, tangents.
first());
182 if (correction_angle >
M_PI) {
183 correction_angle = correction_angle - 2 *
M_PI;
187 const float angle_step = correction_angle /
normals.size();
188 for (
const int i :
normals.index_range()) {
189 const float3 axis = tangents[
i];
193 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)
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)
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)
bool almost_equal_relative(const VecBase< T, Size > &a, const VecBase< T, Size > &b, const T &epsilon_factor)
VecBase< float, 3 > float3