16 const int segment_index)
20 handle_types_left[segment_index + 1]);
35 const int size = handle_types_left.
size();
39 evaluated_offsets.
first() = 1;
47 evaluated_offsets[i] =
offset;
68 BLI_assert(parameter <= 1.0f && parameter >= 0.0f);
82 const float3 &other_handle,
83 const float3 &aligned_handle)
89 return position - dir *
length;
95 const float3 prev_position,
101 const float3 prev_diff = position - prev_position;
105 if (prev_len == 0.0f) {
108 if (next_len == 0.0f) {
111 const float3 dir = next_diff / next_len + prev_diff / prev_len;
117 const float prev_len_clamped =
std::min(prev_len, next_len * 5.0f);
118 left = position + dir * -(prev_len_clamped /
len);
121 const float next_len_clamped =
std::min(next_len, prev_len * 5.0f);
122 right = position + dir * (next_len_clamped /
len);
173 if (points_num == 1) {
182 positions_left.
first(),
183 positions_right.
first());
186 for (
const int i : range) {
202 positions_left.
last(),
203 positions_right.
last());
213 const float inv_len = 1.0f /
static_cast<float>(
result.size());
214 const float inv_len_squared = inv_len * inv_len;
215 const float inv_len_cubed = inv_len_squared * inv_len;
217 const float3 rt1 = 3.0f * (point_1 - point_0) * inv_len;
218 const float3 rt2 = 3.0f * (point_0 - 2.0f * point_1 + point_2) * inv_len_squared;
219 const float3 rt3 = (point_3 - point_0 + 3.0f * (point_1 - point_2)) * inv_len_cubed;
223 float3 q2 = 2.0f * rt2 + 6.0f * rt3;
225 for (
const int i :
result.index_range()) {
241 if (evaluated_offsets.
last() == 1) {
248 handles_right.
first(),
254 const int grain_size = std::max<int>(evaluated_positions.
size() /
positions.size() * 32, 1);
257 for (const int i : range) {
258 const IndexRange evaluated_range = offsets_to_range(evaluated_offsets, i - 1);
259 if (evaluated_range.size() == 1) {
260 evaluated_positions[evaluated_range.first()] = positions[i];
263 evaluate_segment(positions[i],
267 evaluated_positions.slice(evaluated_range));
274 if (last_segment_points.size() == 1) {
275 evaluated_positions.last() =
positions.last();
279 handles_right.last(),
280 handles_left.first(),
282 evaluated_positions.slice(last_segment_points));
290 const float step = 1.0f / dst.
size();
304 if (
src.size() == 1) {
313 src.index_range().drop_back(1).drop_front(1), 512, [&](
IndexRange range) {
314 for (const int i : range) {
315 const IndexRange segment_points = offsets_to_range(evaluated_offsets, i - 1);
316 linear_interpolation(src[i], src[i + 1], dst.slice(segment_points));
320 const IndexRange last_segment_points(evaluated_offsets.last(1),
321 evaluated_offsets.last() - evaluated_offsets.last(1));
328 using T = decltype(dummy);
329 if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
330 interpolate_to_evaluated(src.typed<T>(), evaluated_offsets, dst.typed<T>());
Low-level operations for curves.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr IndexRange drop_back(int64_t n) const
constexpr bool contains(int64_t value) const
constexpr IndexRange drop_front(int64_t n) const
constexpr int64_t size() const
constexpr T & last(const int64_t n=0) const
constexpr IndexRange index_range() const
constexpr T & first() const
constexpr MutableSpan take_front(const int64_t n) const
constexpr const T & first() const
constexpr const T & last(const int64_t n=0) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
SyclQueue void void * src
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void convert_to_static_type(const CPPType &cpp_type, const Func &func)
T mix2(float factor, const T &a, const T &b)
Insertion insert(const float3 &point_prev, const float3 &handle_prev, const float3 &handle_next, const float3 &point_next, float parameter)
bool segment_is_vector(const HandleType left, const HandleType right)
void calculate_auto_handles(bool cyclic, Span< int8_t > types_left, Span< int8_t > types_right, Span< float3 > positions, MutableSpan< float3 > positions_left, MutableSpan< float3 > positions_right)
void calculate_evaluated_offsets(Span< int8_t > handle_types_left, Span< int8_t > handle_types_right, bool cyclic, int resolution, MutableSpan< int > evaluated_offsets)
float3 calculate_vector_handle(const float3 &point, const float3 &next_point)
static void calculate_point_handles(const HandleType type_left, const HandleType type_right, const float3 position, const float3 prev_position, const float3 next_position, float3 &left, float3 &right)
static void interpolate_to_evaluated(const Span< T > src, const Span< int > evaluated_offsets, MutableSpan< T > dst)
void evaluate_segment(const float3 &point_0, const float3 &point_1, const float3 &point_2, const float3 &point_3, MutableSpan< float3 > result)
bool last_cyclic_segment_is_vector(Span< int8_t > handle_types_left, Span< int8_t > handle_types_right)
void calculate_evaluated_positions(Span< float3 > positions, Span< float3 > handles_left, Span< float3 > handles_right, Span< int > evaluated_offsets, MutableSpan< float3 > evaluated_positions)
static float3 calculate_aligned_handle(const float3 &position, const float3 &other_handle, const float3 &aligned_handle)
void set_handle_position(const float3 &position, HandleType type, HandleType type_other, const float3 &new_handle, float3 &handle, float3 &handle_other)
static void linear_interpolation(const T &a, const T &b, MutableSpan< T > dst)
constexpr IndexRange offsets_to_range(Span< T > offsets, int64_t index)
T length(const vec_base< T, Size > &a)
T distance(const T &a, const T &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
T interpolate(const T &a, const T &b, const FactorT &t)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
MutableSpan< float3 > positions
static float3 next_position(Span< float3 > positions, const bool cyclic, const int i)