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;
104 k->
prev->
tan[1], k->
next->
tan[0], points_offset, points_offset_len, handles);
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;
199 float(*points)[3] =
static_cast<float(*)[3]
>(
203 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 0,
sizeof(
float[3]), &points[0][0]);
205 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 1,
sizeof(
float[3]), &points[0][1]);
207 bezt_array, bezt_array_len, resolu,
is_cyclic,
false, 2,
sizeof(
float[3]), &points[0][2]);
209 const uint knots_len = bezt_array_len;
210 Knot *knots =
static_cast<Knot *
>(
MEM_mallocN((
sizeof(*knots) * bezt_array_len), __func__));
213 memcpy(points[points_len], points[0],
sizeof(
float[3]) * points_len);
216 for (
uint i = 0; i < bezt_array_len; i++) {
218 knots[i].
can_remove = (bezt_array[i].
f2 & flag_test) != 0;
220 knots[i].
next = &knots[i + 1];
221 knots[i].
prev = &knots[i - 1];
225 sub_v3_v3v3(knots[i].tan[0], bezt_array[i].vec[0], bezt_array[i].vec[1]);
228 sub_v3_v3v3(knots[i].tan[1], bezt_array[i].vec[1], bezt_array[i].vec[2]);
232 knots[i].
co = bezt_array[i].
vec[1];
238 knots[0].
prev = &knots[bezt_array_last];
239 knots[bezt_array_last].
next = &knots[0];
242 knots[0].
prev =
nullptr;
243 knots[bezt_array_last].
next =
nullptr;
250 curve_decimate(points, points_len, knots, knots_len, error_sq_max, error_target_len);
254 uint knots_len_decimated = knots_len;
257#define HANDLE_UPDATE(a, b) \
259 if (a == HD_VECT) { \
262 else if (ELEM(a, HD_AUTO, HD_AUTO_ANIM)) { \
266 if (ELEM(b, HD_AUTO, HD_AUTO_ANIM)) { \
272 for (
uint i = 0; i < bezt_array_len; i++) {
273 if (knots[i].is_removed) {
275 bezt_array[i].
f2 |= flag_set;
276 knots_len_decimated--;
279 bezt_array[i].
f2 &= char(~flag_set);
281 uint i_prev = (i != 0) ? i - 1 : bezt_array_last;
282 if (knots[i_prev].is_removed) {
284 bezt_array[i].vec[0], bezt_array[i].vec[1], knots[i].tan[0], knots[i].handles[0]);
289 uint i_next = (i != bezt_array_last) ? i + 1 : 0;
290 if (knots[i_next].is_removed) {
292 bezt_array[i].vec[2], bezt_array[i].vec[1], knots[i].tan[1], knots[i].handles[1]);
303 return knots_len_decimated;
309 const float error_sq_max,
310 const uint error_target_len)
331 int i_src = 0, i_dst = 0;
333 while (i_src < nu->pntsu) {
334 if ((bezt_src[i_src].f2 & flag_test) == 0) {
335 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)
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)