29 #include "curve_fit_nd.h"
57 const float (*points)[3],
58 const uint points_len,
60 float r_handle_factors[2])
63 float error_sq = FLT_MAX;
65 float handle_factors[2][3];
67 curve_fit_cubic_to_points_single_fl(&points[0][0],
80 r_handle_factors[0] =
dot_v3v3(tan_l, handle_factors[0]);
82 sub_v3_v3(handle_factors[1], points[points_len - 1]);
83 r_handle_factors[1] =
dot_v3v3(tan_r, handle_factors[1]);
89 const float (*points)[3],
90 const uint points_len,
92 const float error_sq_max)
102 const float(*points_offset)[3];
103 uint points_offset_len;
117 if (cost_sq < error_sq_max) {
145 const uint points_len,
147 const uint knots_len,
149 const uint error_target_len)
152 for (
uint i = 0; i < knots_len; i++) {
153 struct Knot *k = &knots[i];
159 uint knots_len_remaining = knots_len;
161 while ((knots_len_remaining > error_target_len) && (
BLI_heap_is_empty(heap) ==
false)) {
166 k = &knots[
r->knot_index];
177 k_next->
prev = k_prev;
178 k_prev->
next = k_next;
192 knots_len_remaining -= 1;
199 const uint bezt_array_len,
201 const bool is_cyclic,
202 const char flag_test,
204 const float error_sq_max,
205 const uint error_target_len)
207 const uint bezt_array_last = bezt_array_len - 1;
210 float(*points)[3] =
MEM_mallocN((
sizeof(
float[3]) * points_len * (is_cyclic ? 2 : 1)), __func__);
213 bezt_array, bezt_array_len, resolu, is_cyclic,
false, 0,
sizeof(
float[3]), &points[0][0]);
215 bezt_array, bezt_array_len, resolu, is_cyclic,
false, 1,
sizeof(
float[3]), &points[0][1]);
217 bezt_array, bezt_array_len, resolu, is_cyclic,
false, 2,
sizeof(
float[3]), &points[0][2]);
219 const uint knots_len = bezt_array_len;
220 struct Knot *knots =
MEM_mallocN((
sizeof(*knots) * bezt_array_len), __func__);
223 memcpy(points[points_len], points[0],
sizeof(
float[3]) * points_len);
226 for (
uint i = 0; i < bezt_array_len; i++) {
228 knots[i].
can_remove = (bezt_array[i].
f2 & flag_test) != 0;
230 knots[i].
next = &knots[i + 1];
231 knots[i].
prev = &knots[i - 1];
235 sub_v3_v3v3(knots[i].
tan[0], bezt_array[i].vec[0], bezt_array[i].vec[1]);
238 sub_v3_v3v3(knots[i].
tan[1], bezt_array[i].vec[1], bezt_array[i].vec[2]);
242 knots[i].
co = bezt_array[i].
vec[1];
248 knots[0].
prev = &knots[bezt_array_last];
249 knots[bezt_array_last].
next = &knots[0];
260 curve_decimate(points, points_len, knots, knots_len, error_sq_max, error_target_len);
264 uint knots_len_decimated = knots_len;
267 #define HANDLE_UPDATE(a, b) \
269 if (a == HD_VECT) { \
272 else if (ELEM(a, HD_AUTO, HD_AUTO_ANIM)) { \
276 if (ELEM(b, HD_AUTO, HD_AUTO_ANIM)) { \
282 for (
uint i = 0; i < bezt_array_len; i++) {
285 bezt_array[i].
f2 |= flag_set;
286 knots_len_decimated--;
289 bezt_array[i].
f2 &= (char)~flag_set;
290 if (is_cyclic || i != 0) {
291 uint i_prev = (i != 0) ? i - 1 : bezt_array_last;
294 bezt_array[i].vec[0], bezt_array[i].vec[1], knots[i].
tan[0], knots[i].
handles[0]);
298 if (is_cyclic || i != bezt_array_last) {
299 uint i_next = (i != bezt_array_last) ? i + 1 : 0;
302 bezt_array[i].vec[2], bezt_array[i].vec[1], knots[i].
tan[1], knots[i].
handles[1]);
313 return knots_len_decimated;
319 const float error_sq_max,
320 const uint error_target_len)
340 int i_src = 0, i_dst = 0;
342 while (i_src < nu->pntsu) {
343 if ((bezt_src[i_src].f2 & flag_test) == 0) {
344 bezt_dst[i_dst] = bezt_src[i_src];
typedef float(TangentPoint)[2]
unsigned int BKE_curve_calc_coords_axis_len(const unsigned int bezt_array_len, const unsigned int resolu, const bool is_cyclic, const bool use_cyclic_duplicate_endpoint)
void BKE_curve_calc_coords_axis(const struct BezTriple *bezt_array, const unsigned int bezt_array_len, const unsigned int resolu, const bool is_cyclic, const bool use_cyclic_duplicate_endpoint, const unsigned int axis, const unsigned int stride, float *r_points)
A min-heap / priority queue ADT.
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
Heap * BLI_heap_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT
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)
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)
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)