15 #include "curve_fit_nd.h"
43 const float (*points)[3],
44 const uint points_len,
46 float r_handle_factors[2])
49 float error_sq = FLT_MAX;
51 float handle_factors[2][3];
53 curve_fit_cubic_to_points_single_fl(&points[0][0],
66 r_handle_factors[0] =
dot_v3v3(tan_l, handle_factors[0]);
68 sub_v3_v3(handle_factors[1], points[points_len - 1]);
69 r_handle_factors[1] =
dot_v3v3(tan_r, handle_factors[1]);
75 const float (*points)[3],
76 const uint points_len,
78 const float error_sq_max)
88 const float(*points_offset)[3];
89 uint points_offset_len;
103 if (cost_sq < error_sq_max) {
131 const uint points_len,
133 const uint knots_len,
135 const uint error_target_len)
138 for (
uint i = 0; i < knots_len; i++) {
139 struct Knot *k = &knots[i];
145 uint knots_len_remaining = knots_len;
147 while ((knots_len_remaining > error_target_len) && (
BLI_heap_is_empty(heap) ==
false)) {
152 k = &knots[
r->knot_index];
163 k_next->
prev = k_prev;
164 k_prev->
next = k_next;
178 knots_len_remaining -= 1;
185 const uint bezt_array_len,
188 const char flag_test,
190 const float error_sq_max,
191 const uint error_target_len)
193 const uint bezt_array_last = bezt_array_len - 1;
199 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 0,
sizeof(
float[3]), &points[0][0]);
201 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 1,
sizeof(
float[3]), &points[0][1]);
203 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 2,
sizeof(
float[3]), &points[0][2]);
205 const uint knots_len = bezt_array_len;
206 struct Knot *knots =
MEM_mallocN((
sizeof(*knots) * bezt_array_len), __func__);
209 memcpy(points[points_len], points[0],
sizeof(
float[3]) * points_len);
212 for (
uint i = 0; i < bezt_array_len; i++) {
214 knots[i].
can_remove = (bezt_array[i].
f2 & flag_test) != 0;
216 knots[i].
next = &knots[i + 1];
217 knots[i].
prev = &knots[i - 1];
221 sub_v3_v3v3(knots[i].
tan[0], bezt_array[i].vec[0], bezt_array[i].vec[1]);
224 sub_v3_v3v3(knots[i].
tan[1], bezt_array[i].vec[1], bezt_array[i].vec[2]);
228 knots[i].
co = bezt_array[i].
vec[1];
234 knots[0].
prev = &knots[bezt_array_last];
235 knots[bezt_array_last].
next = &knots[0];
246 curve_decimate(points, points_len, knots, knots_len, error_sq_max, error_target_len);
250 uint knots_len_decimated = knots_len;
253 #define HANDLE_UPDATE(a, b) \
255 if (a == HD_VECT) { \
258 else if (ELEM(a, HD_AUTO, HD_AUTO_ANIM)) { \
262 if (ELEM(b, HD_AUTO, HD_AUTO_ANIM)) { \
268 for (
uint i = 0; i < bezt_array_len; i++) {
271 bezt_array[i].
f2 |= flag_set;
272 knots_len_decimated--;
275 bezt_array[i].
f2 &= (char)~flag_set;
277 uint i_prev = (i != 0) ? i - 1 : bezt_array_last;
280 bezt_array[i].vec[0], bezt_array[i].vec[1], knots[i].
tan[0], knots[i].
handles[0]);
285 uint i_next = (i != bezt_array_last) ? i + 1 : 0;
288 bezt_array[i].vec[2], bezt_array[i].vec[1], knots[i].
tan[1], knots[i].
handles[1]);
299 return knots_len_decimated;
305 const float error_sq_max,
306 const uint error_target_len)
326 int i_src = 0, i_dst = 0;
328 while (i_src < nu->pntsu) {
329 if ((bezt_src[i_src].f2 & flag_test) == 0) {
330 bezt_dst[i_dst] = bezt_src[i_src];
typedef float(TangentPoint)[2]
unsigned int BKE_curve_calc_coords_axis_len(unsigned int bezt_array_len, unsigned int resolu, bool is_cyclic, bool use_cyclic_duplicate_endpoint)
void BKE_curve_calc_coords_axis(const struct BezTriple *bezt_array, unsigned int bezt_array_len, unsigned int resolu, bool is_cyclic, bool use_cyclic_duplicate_endpoint, unsigned int axis, unsigned int stride, float *r_points)
A min-heap / priority queue ADT.
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr) ATTR_NONNULL(1
void void bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1)
void * BLI_heap_pop_min(Heap *heap) ATTR_NONNULL(1)
Heap * BLI_heap_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
void * BLI_heap_node_ptr(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE bool equals_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
_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 GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
Read Guarded memory(de)allocation.
#define HANDLE_UPDATE(a, b)
void BKE_curve_decimate_nurb(Nurb *nu, const uint resolu, const float error_sq_max, const uint error_target_len)
uint BKE_curve_decimate_bezt_array(BezTriple *bezt_array, const uint bezt_array_len, const uint resolu, const bool is_cyclic, const char flag_test, const char flag_set, const float error_sq_max, const uint error_target_len)
static void knot_remove_error_recalculate(Heap *heap, const float(*points)[3], const uint points_len, struct Knot *k, const float error_sq_max)
static float knot_remove_error_value(const float tan_l[3], const float tan_r[3], const float(*points)[3], const uint points_len, float r_handle_factors[2])
static void curve_decimate(const float(*points)[3], const uint points_len, struct Knot *knots, const uint knots_len, float error_sq_max, const uint error_target_len)
static bool is_cyclic(const Nurb *nu)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN)(size_t len, const char *str)
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)