18#include "curve_fit_nd.h"
49 const float (*points)[3],
50 const uint points_len,
52 float r_handle_factors[2])
57 float handle_factors[2][3];
59 curve_fit_cubic_to_points_single_fl(&points[0][0],
72 r_handle_factors[0] =
dot_v3v3(tan_l, handle_factors[0]);
74 sub_v3_v3(handle_factors[1], points[points_len - 1]);
75 r_handle_factors[1] =
dot_v3v3(tan_r, handle_factors[1]);
81 Heap *heap,
const float (*points)[3],
const uint points_len,
Knot *k,
const float error_sq_max)
91 const float (*points_offset)[3];
92 uint points_offset_len;
106 if (cost_sq < error_sq_max) {
134 const uint points_len,
136 const uint knots_len,
138 const uint error_target_len)
141 for (
uint i = 0;
i < knots_len;
i++) {
148 uint knots_len_remaining = knots_len;
150 while ((knots_len_remaining > error_target_len) && (
BLI_heap_is_empty(heap) ==
false)) {
166 k_next->
prev = k_prev;
167 k_prev->
next = k_next;
181 knots_len_remaining -= 1;
188 const uint bezt_array_len,
191 const char flag_test,
193 const float error_sq_max,
194 const uint error_target_len)
196 const uint bezt_array_last = bezt_array_len - 1;
202 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 0,
sizeof(
float[3]), &points[0][0]);
204 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 1,
sizeof(
float[3]), &points[0][1]);
206 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 2,
sizeof(
float[3]), &points[0][2]);
208 const uint knots_len = bezt_array_len;
212 memcpy(points[points_len], points[0],
sizeof(
float[3]) * points_len);
215 for (
uint i = 0;
i < bezt_array_len;
i++) {
219 knots[
i].
next = &knots[
i + 1];
220 knots[
i].
prev = &knots[
i - 1];
231 knots[
i].
co = bezt_array[
i].
vec[1];
237 knots[0].
prev = &knots[bezt_array_last];
238 knots[bezt_array_last].
next = &knots[0];
241 knots[0].
prev =
nullptr;
242 knots[bezt_array_last].
next =
nullptr;
249 curve_decimate(points, points_len, knots, knots_len, error_sq_max, error_target_len);
253 uint knots_len_decimated = knots_len;
256#define HANDLE_UPDATE(a, b) \
258 if (a == HD_VECT) { \
261 else if (ELEM(a, HD_AUTO, HD_AUTO_ANIM)) { \
265 if (ELEM(b, HD_AUTO, HD_AUTO_ANIM)) { \
271 for (
uint i = 0;
i < bezt_array_len;
i++) {
272 if (knots[
i].is_removed) {
274 bezt_array[
i].
f2 |= flag_set;
275 knots_len_decimated--;
278 bezt_array[
i].
f2 &= char(~flag_set);
280 uint i_prev = (
i != 0) ?
i - 1 : bezt_array_last;
281 if (knots[i_prev].is_removed) {
283 bezt_array[
i].vec[0], bezt_array[
i].vec[1], knots[
i].
tan[0], knots[
i].
handles[0]);
288 uint i_next = (
i != bezt_array_last) ?
i + 1 : 0;
289 if (knots[i_next].is_removed) {
291 bezt_array[
i].vec[2], bezt_array[
i].vec[1], knots[
i].
tan[1], knots[
i].
handles[1]);
302 return knots_len_decimated;
308 const float error_sq_max,
309 const uint error_target_len)
329 int i_src = 0, i_dst = 0;
331 while (i_src < nu->pntsu) {
332 if ((bezt_src[i_src].f2 & flag_test) == 0) {
333 bezt_dst[i_dst] = bezt_src[i_src];
void BKE_curve_calc_coords_axis(const 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)
unsigned int BKE_curve_calc_coords_axis_len(unsigned int bezt_array_len, unsigned int resolu, bool is_cyclic, bool use_cyclic_duplicate_endpoint)
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
Heap * BLI_heap_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
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 void sub_v3_v3(float r[3], const float a[3])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
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 void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE float normalize_v3(float n[3])
Read Guarded memory(de)allocation.
#define HANDLE_UPDATE(a, b)
static void curve_decimate(const float(*points)[3], const uint points_len, Knot *knots, const uint knots_len, float error_sq_max, const uint error_target_len)
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 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 knot_remove_error_recalculate(Heap *heap, const float(*points)[3], const uint points_len, Knot *k, const float error_sq_max)
static bool is_cyclic(const Nurb *nu)
void * MEM_mallocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)