Add Chromium-only Blender WebEngine parity work
This commit is contained in:
30
blender-5.2.0/extern/curve_fit_nd/CMakeLists.txt
vendored
Normal file
30
blender-5.2.0/extern/curve_fit_nd/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# SPDX-FileCopyrightText: 2002-2022 Blender Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(INC
|
||||
PUBLIC .
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/curve_fit_cubic.c
|
||||
intern/curve_fit_cubic_refit.c
|
||||
intern/curve_fit_corners_detect.c
|
||||
|
||||
curve_fit_nd.h
|
||||
intern/curve_fit_inline.h
|
||||
intern/curve_fit_intern.h
|
||||
intern/generic_alloc_impl.h
|
||||
intern/generic_heap.c
|
||||
intern/generic_heap.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
blender_add_lib(extern_curve_fit_nd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
add_library(bf::extern::curve_fit_nd ALIAS extern_curve_fit_nd)
|
||||
6
blender-5.2.0/extern/curve_fit_nd/README.blender
vendored
Normal file
6
blender-5.2.0/extern/curve_fit_nd/README.blender
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
Project: Curve-Fit-nD
|
||||
URL: https://github.com/ideasman42/curve-fit-nd
|
||||
License: SPDX:BSD-3-Clause
|
||||
Upstream version: 5d75a7adbc2451420a13323496c13b5d20184f54
|
||||
Local modifications: None
|
||||
Copyright: Copyright (c) 2016, DWANGO Co., Ltd.; Copyright (c) 2016, Campbell Barton; All rights reserved.
|
||||
205
blender-5.2.0/extern/curve_fit_nd/curve_fit_nd.h
vendored
Normal file
205
blender-5.2.0/extern/curve_fit_nd/curve_fit_nd.h
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2016, DWANGO Co., Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __CURVE_FIT_ND_H__
|
||||
#define __CURVE_FIT_ND_H__
|
||||
|
||||
/** \file curve_fit_nd.h
|
||||
* \ingroup curve_fit
|
||||
*/
|
||||
|
||||
|
||||
/* curve_fit_cubic.c */
|
||||
|
||||
/**
|
||||
* Takes a flat array of points and evaluates that to calculate a Bezier spline.
|
||||
*
|
||||
* \param points, points_len: The array of points to calculate cubics from.
|
||||
* \param dims: The number of dimensions for each element in \a points.
|
||||
* \param error_threshold: The error threshold to allow for,
|
||||
* the curve will be within this distance from \a points.
|
||||
* \param corners, corners_len: Indices for points which will not have aligned tangents (optional).
|
||||
* This can use the output of #curve_fit_corners_detect_db which has been included
|
||||
* to evaluate a line to detect corner indices.
|
||||
*
|
||||
* \param r_cubic_array, r_cubic_array_len: Resulting array of tangents and knots, formatted as follows:
|
||||
* `r_cubic_array[r_cubic_array_len][3][dims]`,
|
||||
* where each point has 0 and 2 for the tangents and the middle index 1 for the knot.
|
||||
* The size of the *flat* array will be `r_cubic_array_len * 3 * dims`.
|
||||
* \param r_corner_index_array, r_corner_index_len: Corner indices in \a r_cubic_array (optional).
|
||||
* This allows you to access corners on the resulting curve.
|
||||
*
|
||||
* \returns zero on success, nonzero is reserved for error values.
|
||||
*/
|
||||
int curve_fit_cubic_to_points_db(
|
||||
const double *points,
|
||||
const unsigned int points_len,
|
||||
const unsigned int dims,
|
||||
const double error_threshold,
|
||||
const unsigned int calc_flag,
|
||||
const unsigned int *corners,
|
||||
unsigned int corners_len,
|
||||
|
||||
double **r_cubic_array, unsigned int *r_cubic_array_len,
|
||||
unsigned int **r_cubic_orig_index,
|
||||
unsigned int **r_corner_index_array, unsigned int *r_corner_index_len);
|
||||
|
||||
int curve_fit_cubic_to_points_fl(
|
||||
const float *points,
|
||||
const unsigned int points_len,
|
||||
const unsigned int dims,
|
||||
const float error_threshold,
|
||||
const unsigned int calc_flag,
|
||||
const unsigned int *corners,
|
||||
const unsigned int corners_len,
|
||||
|
||||
float **r_cubic_array, unsigned int *r_cubic_array_len,
|
||||
unsigned int **r_cubic_orig_index,
|
||||
unsigned int **r_corners_index_array, unsigned int *r_corners_index_len);
|
||||
|
||||
/**
|
||||
* Takes a flat array of points and evaluates that to calculate handle lengths.
|
||||
*
|
||||
* \param points, points_len: The array of points to calculate cubics from.
|
||||
* \param dims: The number of dimensions for each element in \a points.
|
||||
* \param points_length_cache: Optional pre-calculated lengths between points.
|
||||
* \param error_threshold: The error threshold to allow for.
|
||||
* \param tan_l, tan_r: Normalized tangents the handles will be aligned to.
|
||||
* Note that tangents must both point along the direction of the \a points,
|
||||
* so \a tan_l points in the same direction of the resulting handle,
|
||||
* where \a tan_r will point the opposite direction of its handle.
|
||||
*
|
||||
* \param r_handle_l, r_handle_r: Resulting calculated handles.
|
||||
* \param r_error_sq: The maximum distance (squared) this curve diverges from \a points.
|
||||
*/
|
||||
int curve_fit_cubic_to_points_single_db(
|
||||
const double *points,
|
||||
const unsigned int points_len,
|
||||
const double *points_length_cache,
|
||||
const unsigned int dims,
|
||||
const double error_threshold,
|
||||
const double tan_l[],
|
||||
const double tan_r[],
|
||||
|
||||
double r_handle_l[],
|
||||
double r_handle_r[],
|
||||
double *r_error_sq,
|
||||
unsigned int *r_error_index);
|
||||
|
||||
int curve_fit_cubic_to_points_single_fl(
|
||||
const float *points,
|
||||
const unsigned int points_len,
|
||||
const float *points_length_cache,
|
||||
const unsigned int dims,
|
||||
const float error_threshold,
|
||||
const float tan_l[],
|
||||
const float tan_r[],
|
||||
|
||||
float r_handle_l[],
|
||||
float r_handle_r[],
|
||||
float *r_error_sq,
|
||||
unsigned int *r_error_index);
|
||||
|
||||
enum {
|
||||
CURVE_FIT_CALC_HIGH_QUALITY = (1 << 0),
|
||||
CURVE_FIT_CALC_CYCLIC = (1 << 1),
|
||||
};
|
||||
|
||||
|
||||
/* curve_fit_cubic_refit.c */
|
||||
|
||||
int curve_fit_cubic_to_points_refit_db(
|
||||
const double *points,
|
||||
const unsigned int points_len,
|
||||
const unsigned int dims,
|
||||
const double error_threshold,
|
||||
const unsigned int calc_flag,
|
||||
const unsigned int *corners,
|
||||
const unsigned int corners_len,
|
||||
const double corner_angle,
|
||||
|
||||
double **r_cubic_array, unsigned int *r_cubic_array_len,
|
||||
unsigned int **r_cubic_orig_index,
|
||||
unsigned int **r_corner_index_array, unsigned int *r_corner_index_len);
|
||||
|
||||
int curve_fit_cubic_to_points_refit_fl(
|
||||
const float *points,
|
||||
const unsigned int points_len,
|
||||
const unsigned int dims,
|
||||
const float error_threshold,
|
||||
const unsigned int calc_flag,
|
||||
const unsigned int *corners,
|
||||
unsigned int corners_len,
|
||||
const float corner_angle,
|
||||
|
||||
float **r_cubic_array, unsigned int *r_cubic_array_len,
|
||||
unsigned int **r_cubic_orig_index,
|
||||
unsigned int **r_corner_index_array, unsigned int *r_corner_index_len);
|
||||
|
||||
/* curve_fit_corners_detect.c */
|
||||
|
||||
/**
|
||||
* A helper function that takes a line and outputs its corner indices.
|
||||
*
|
||||
* \param points, points_len: Curve to evaluate.
|
||||
* \param dims: The number of dimensions for each element in \a points.
|
||||
* \param radius_min: Corners on the curve between points below this radius are ignored.
|
||||
* \param radius_max: Corners on the curve above this radius are ignored.
|
||||
* \param samples_max: Prevent testing corners beyond this many points
|
||||
* (prevents a large radius taking excessive time to compute).
|
||||
* \param angle_threshold: Angles above this value are considered corners
|
||||
* (higher value for fewer corners).
|
||||
*
|
||||
* \param r_corners, r_corners_len: Resulting array of corners.
|
||||
*
|
||||
* \returns zero on success, nonzero is reserved for error values.
|
||||
*/
|
||||
int curve_fit_corners_detect_db(
|
||||
const double *points,
|
||||
const unsigned int points_len,
|
||||
const unsigned int dims,
|
||||
const double radius_min,
|
||||
const double radius_max,
|
||||
const unsigned int samples_max,
|
||||
const double angle_threshold,
|
||||
|
||||
unsigned int **r_corners,
|
||||
unsigned int *r_corners_len);
|
||||
|
||||
int curve_fit_corners_detect_fl(
|
||||
const float *points,
|
||||
const unsigned int points_len,
|
||||
const unsigned int dims,
|
||||
const float radius_min,
|
||||
const float radius_max,
|
||||
const unsigned int samples_max,
|
||||
const float angle_threshold,
|
||||
|
||||
unsigned int **r_corners,
|
||||
unsigned int *r_corners_len);
|
||||
|
||||
#endif /* __CURVE_FIT_ND_H__ */
|
||||
466
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_corners_detect.c
vendored
Normal file
466
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_corners_detect.c
vendored
Normal file
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file curve_fit_corners_detect.c
|
||||
* \ingroup curve_fit
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../curve_fit_nd.h"
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#include "curve_fit_inline.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define alloca(size) _alloca(size)
|
||||
#endif
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
# define USE_VLA
|
||||
#endif
|
||||
|
||||
#ifdef USE_VLA
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wvla"
|
||||
# endif
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic error "-Wvla"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Simple Vector Math Lib
|
||||
* \{ */
|
||||
|
||||
static double cos_vnvnvn(
|
||||
const double v0[], const double v1[], const double v2[],
|
||||
const uint dims)
|
||||
{
|
||||
#ifdef USE_VLA
|
||||
double dvec0[dims];
|
||||
double dvec1[dims];
|
||||
#else
|
||||
double *dvec0 = alloca(sizeof(double) * dims);
|
||||
double *dvec1 = alloca(sizeof(double) * dims);
|
||||
#endif
|
||||
normalize_vn_vnvn(dvec0, v0, v1, dims);
|
||||
normalize_vn_vnvn(dvec1, v1, v2, dims);
|
||||
double d = dot_vnvn(dvec0, dvec1, dims);
|
||||
/* Sanity check. */
|
||||
d = max(-1.0, min(1.0, d));
|
||||
return d;
|
||||
}
|
||||
|
||||
static double angle_vnvnvn(
|
||||
const double v0[], const double v1[], const double v2[],
|
||||
const uint dims)
|
||||
{
|
||||
return acos(cos_vnvnvn(v0, v1, v2, dims));
|
||||
}
|
||||
|
||||
|
||||
static bool isect_line_sphere_vn(
|
||||
const double l1[],
|
||||
const double l2[],
|
||||
const double sp[],
|
||||
const double r,
|
||||
uint dims,
|
||||
|
||||
double r_p1[]
|
||||
#if 0 /* UNUSED */
|
||||
double r_p2[]
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef USE_VLA
|
||||
double ldir[dims];
|
||||
double tvec[dims];
|
||||
#else
|
||||
double *ldir = alloca(sizeof(double) * dims);
|
||||
double *tvec = alloca(sizeof(double) * dims);
|
||||
#endif
|
||||
|
||||
sub_vn_vnvn(ldir, l2, l1, dims);
|
||||
|
||||
sub_vn_vnvn(tvec, l1, sp, dims);
|
||||
const double a = len_squared_vn(ldir, dims);
|
||||
const double b = 2.0 * dot_vnvn(ldir, tvec, dims);
|
||||
const double c = len_squared_vn(sp, dims) + len_squared_vn(l1, dims) - (2.0 * dot_vnvn(sp, l1, dims)) - sq(r);
|
||||
|
||||
const double i = b * b - 4.0 * a * c;
|
||||
|
||||
if ((i < 0.0) || (a == 0.0)) {
|
||||
return false;
|
||||
}
|
||||
else if (i == 0.0) {
|
||||
/* One intersection. */
|
||||
const double mu = -b / (2.0 * a);
|
||||
mul_vnvn_fl(r_p1, ldir, mu, dims);
|
||||
iadd_vnvn(r_p1, l1, dims);
|
||||
return true;
|
||||
}
|
||||
else if (i > 0.0) {
|
||||
/* Avoid calculating twice. */
|
||||
const double i_sqrt = sqrt(i);
|
||||
double mu;
|
||||
|
||||
/* Note: when l1 is inside the sphere and l2 is outside,
|
||||
* the first intersection point will always be between the pair. */
|
||||
|
||||
/* First intersection. */
|
||||
mu = (-b + i_sqrt) / (2.0 * a);
|
||||
mul_vnvn_fl(r_p1, ldir, mu, dims);
|
||||
iadd_vnvn(r_p1, l1, dims);
|
||||
#if 0
|
||||
/* Second intersection. */
|
||||
mu = (-b - i_sqrt) / (2.0 * a);
|
||||
mul_vnvn_fl(r_p2, ldir, mu, dims);
|
||||
iadd_vnvn(r_p2, l1, dims);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
||||
static bool point_corner_measure(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint i,
|
||||
const uint i_prev_init,
|
||||
const uint i_next_init,
|
||||
const double radius,
|
||||
const uint samples_max,
|
||||
const uint dims,
|
||||
|
||||
double r_p_prev[], uint *r_i_prev_next,
|
||||
double r_p_next[], uint *r_i_next_prev)
|
||||
{
|
||||
const double *p = &points[i * dims];
|
||||
const double radius_sq = sq(radius);
|
||||
uint sample;
|
||||
|
||||
|
||||
uint i_prev = i_prev_init;
|
||||
uint i_prev_next = i_prev + 1;
|
||||
sample = 0;
|
||||
while (true) {
|
||||
if ((i_prev == -1) || (sample++ > samples_max)) {
|
||||
return false;
|
||||
}
|
||||
else if (len_squared_vnvn(p, &points[i_prev * dims], dims) < radius_sq) {
|
||||
i_prev -= 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint i_next = i_next_init;
|
||||
uint i_next_prev = i_next - 1;
|
||||
sample = 0;
|
||||
while (true) {
|
||||
if ((i_next == points_len) || (sample++ > samples_max)) {
|
||||
return false;
|
||||
}
|
||||
else if (len_squared_vnvn(p, &points[i_next * dims], dims) < radius_sq) {
|
||||
i_next += 1;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find points on the sphere. */
|
||||
if (!isect_line_sphere_vn(
|
||||
&points[i_prev * dims], &points[i_prev_next * dims], p, radius, dims,
|
||||
r_p_prev))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isect_line_sphere_vn(
|
||||
&points[i_next * dims], &points[i_next_prev * dims], p, radius, dims,
|
||||
r_p_next))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*r_i_prev_next = i_prev_next;
|
||||
*r_i_next_prev = i_next_prev;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static double point_corner_angle(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint i,
|
||||
const double radius_mid,
|
||||
const double radius_max,
|
||||
const double angle_threshold,
|
||||
const double angle_threshold_cos,
|
||||
/* Prevent locking up when for example `radius_min` is very large
|
||||
* (possibly larger than the curve).
|
||||
* In this case we would end up checking every point from every other point,
|
||||
* never reaching one that was outside the `radius_min`. */
|
||||
const uint samples_max,
|
||||
|
||||
const uint dims)
|
||||
{
|
||||
assert(angle_threshold_cos == cos(angle_threshold));
|
||||
|
||||
if (i == 0 || i == points_len - 1) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const double *p = &points[i * dims];
|
||||
|
||||
/* Initial test. */
|
||||
if (cos_vnvnvn(&points[(i - 1) * dims], p, &points[(i + 1) * dims], dims) > angle_threshold_cos) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
#ifdef USE_VLA
|
||||
double p_mid_prev[dims];
|
||||
double p_mid_next[dims];
|
||||
#else
|
||||
double *p_mid_prev = alloca(sizeof(double) * dims);
|
||||
double *p_mid_next = alloca(sizeof(double) * dims);
|
||||
#endif
|
||||
|
||||
uint i_mid_prev_next, i_mid_next_prev;
|
||||
if (point_corner_measure(
|
||||
points, points_len,
|
||||
i, i - 1, i + 1,
|
||||
radius_mid,
|
||||
samples_max,
|
||||
dims,
|
||||
|
||||
p_mid_prev, &i_mid_prev_next,
|
||||
p_mid_next, &i_mid_next_prev))
|
||||
{
|
||||
const double angle_mid_cos = cos_vnvnvn(p_mid_prev, p, p_mid_next, dims);
|
||||
|
||||
/* Compare as cos and flip direction. */
|
||||
|
||||
/* if (angle_mid > angle_threshold) { */
|
||||
if (angle_mid_cos < angle_threshold_cos) {
|
||||
#ifdef USE_VLA
|
||||
double p_max_prev[dims];
|
||||
double p_max_next[dims];
|
||||
#else
|
||||
double *p_max_prev = alloca(sizeof(double) * dims);
|
||||
double *p_max_next = alloca(sizeof(double) * dims);
|
||||
#endif
|
||||
|
||||
uint i_max_prev_next, i_max_next_prev;
|
||||
if (point_corner_measure(
|
||||
points, points_len,
|
||||
i, i - 1, i + 1,
|
||||
radius_max,
|
||||
samples_max,
|
||||
dims,
|
||||
|
||||
p_max_prev, &i_max_prev_next,
|
||||
p_max_next, &i_max_next_prev))
|
||||
{
|
||||
const double angle_mid = acos(angle_mid_cos);
|
||||
const double angle_max = angle_vnvnvn(p_max_prev, p, p_max_next, dims) / 2.0;
|
||||
const double angle_diff = angle_mid - angle_max;
|
||||
if (angle_diff > angle_threshold) {
|
||||
return angle_diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
int curve_fit_corners_detect_db(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint dims,
|
||||
const double radius_min, /* ignore values below this */
|
||||
const double radius_max, /* ignore values above this */
|
||||
const uint samples_max,
|
||||
const double angle_threshold,
|
||||
|
||||
uint **r_corners,
|
||||
uint *r_corners_len)
|
||||
{
|
||||
const double angle_threshold_cos = cos(angle_threshold);
|
||||
uint corners_len = 0;
|
||||
|
||||
/* Use the difference in angle between the mid-max radii
|
||||
* to detect the difference between a corner and a sharp turn. */
|
||||
const double radius_mid = (radius_min + radius_max) / 2.0;
|
||||
|
||||
/* We could ignore first/last, but simple to keep aligned with the point array. */
|
||||
double *points_angle = malloc(sizeof(double) * points_len);
|
||||
points_angle[0] = 0.0;
|
||||
|
||||
*r_corners = NULL;
|
||||
*r_corners_len = 0;
|
||||
|
||||
for (uint i = 0; i < points_len; i++) {
|
||||
points_angle[i] = point_corner_angle(
|
||||
points, points_len, i,
|
||||
radius_mid, radius_max,
|
||||
angle_threshold, angle_threshold_cos,
|
||||
samples_max,
|
||||
dims);
|
||||
|
||||
if (points_angle[i] != 0.0) {
|
||||
corners_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (corners_len == 0) {
|
||||
free(points_angle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clean angle limits!
|
||||
*
|
||||
* How this works:
|
||||
* - Find contiguous 'corners' (where the distance is less or equal to the error threshold).
|
||||
* - Keep track of the corner with the highest angle
|
||||
* - Clear every other angle (so they're ignored when setting corners). */
|
||||
{
|
||||
const double radius_min_sq = sq(radius_min);
|
||||
uint i_span_start = 0;
|
||||
while (i_span_start < points_len) {
|
||||
uint i_span_end = i_span_start;
|
||||
if (points_angle[i_span_start] != 0.0) {
|
||||
uint i_next = i_span_start + 1;
|
||||
uint i_best = i_span_start;
|
||||
while (i_next < points_len) {
|
||||
if ((points_angle[i_next] == 0.0) ||
|
||||
(len_squared_vnvn(
|
||||
&points[(i_next - 1) * dims],
|
||||
&points[i_next * dims], dims) > radius_min_sq))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (points_angle[i_best] < points_angle[i_next]) {
|
||||
i_best = i_next;
|
||||
}
|
||||
i_span_end = i_next;
|
||||
i_next += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_span_start != i_span_end) {
|
||||
uint i = i_span_start;
|
||||
while (i <= i_span_end) {
|
||||
if (i != i_best) {
|
||||
/* We could use some other error code. */
|
||||
assert(points_angle[i] != 0.0);
|
||||
points_angle[i] = 0.0;
|
||||
corners_len--;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
i_span_start = i_span_end + 1;
|
||||
}
|
||||
}
|
||||
/* End angle limit cleaning! */
|
||||
|
||||
corners_len += 2; /* first and last */
|
||||
uint *corners = malloc(sizeof(uint) * corners_len);
|
||||
uint i_corner = 0;
|
||||
corners[i_corner++] = 0;
|
||||
for (uint i = 0; i < points_len; i++) {
|
||||
if (points_angle[i] != 0.0) {
|
||||
corners[i_corner++] = i;
|
||||
}
|
||||
}
|
||||
corners[i_corner++] = points_len - 1;
|
||||
assert(i_corner == corners_len);
|
||||
|
||||
free(points_angle);
|
||||
|
||||
*r_corners = corners;
|
||||
*r_corners_len = corners_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int curve_fit_corners_detect_fl(
|
||||
const float *points,
|
||||
const uint points_len,
|
||||
const uint dims,
|
||||
const float radius_min, /* ignore values below this */
|
||||
const float radius_max, /* ignore values above this */
|
||||
const uint samples_max,
|
||||
const float angle_threshold,
|
||||
|
||||
uint **r_corners,
|
||||
uint *r_corners_len)
|
||||
{
|
||||
const uint points_flat_len = points_len * dims;
|
||||
double *points_db = malloc(sizeof(double) * points_flat_len);
|
||||
|
||||
for (uint i = 0; i < points_flat_len; i++) {
|
||||
points_db[i] = (double)points[i];
|
||||
}
|
||||
|
||||
int result = curve_fit_corners_detect_db(
|
||||
points_db, points_len,
|
||||
dims,
|
||||
radius_min, radius_max,
|
||||
samples_max,
|
||||
angle_threshold,
|
||||
r_corners, r_corners_len);
|
||||
|
||||
free(points_db);
|
||||
|
||||
return result;
|
||||
}
|
||||
2156
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_cubic.c
vendored
Normal file
2156
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_cubic.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1756
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c
vendored
Normal file
1756
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_cubic_refit.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
316
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_inline.h
vendored
Normal file
316
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_inline.h
vendored
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
/** \file curve_fit_inline.h
|
||||
* \ingroup curve_fit
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Simple Vector Math Lib
|
||||
* \{ */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define MINLINE static __forceinline
|
||||
#else
|
||||
# define MINLINE static inline
|
||||
#endif
|
||||
|
||||
MINLINE double sq(const double d)
|
||||
{
|
||||
return d * d;
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
MINLINE double min(const double a, const double b)
|
||||
{
|
||||
return b < a ? b : a;
|
||||
}
|
||||
|
||||
MINLINE double max(const double a, const double b)
|
||||
{
|
||||
return a < b ? b : a;
|
||||
}
|
||||
#endif
|
||||
|
||||
MINLINE void zero_vn(
|
||||
double v0[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void flip_vn_vnvn(
|
||||
double v_out[], const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] = v0[j] + (v0[j] - v1[j]);
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void copy_vnvn(
|
||||
double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] = v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void copy_vnfl_vndb(
|
||||
float v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] = (float)v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void copy_vndb_vnfl(
|
||||
double v0[], const float v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] = (double)v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE double dot_vnvn(
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
double d = 0.0;
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
d += v0[j] * v1[j];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
MINLINE void add_vn_vnvn(
|
||||
double v_out[], const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] = v0[j] + v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void sub_vn_vnvn(
|
||||
double v_out[], const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] = v0[j] - v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void iadd_vnvn(
|
||||
double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] += v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void isub_vnvn(
|
||||
double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] -= v1[j];
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void madd_vn_vnvn_fl(
|
||||
double v_out[],
|
||||
const double v0[], const double v1[],
|
||||
const double f, const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] = v0[j] + v1[j] * f;
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void msub_vn_vnvn_fl(
|
||||
double v_out[],
|
||||
const double v0[], const double v1[],
|
||||
const double f, const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] = v0[j] - v1[j] * f;
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void miadd_vn_vn_fl(
|
||||
double v_out[], const double v0[], double f, const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] += v0[j] * f;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
MINLINE void misub_vn_vn_fl(
|
||||
double v_out[], const double v0[], double f, const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] -= v0[j] * f;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
MINLINE void mul_vnvn_fl(
|
||||
double v_out[],
|
||||
const double v0[], const double f, const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v_out[j] = v0[j] * f;
|
||||
}
|
||||
}
|
||||
|
||||
MINLINE void imul_vn_fl(double v0[], const double f, const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
v0[j] *= f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MINLINE double len_squared_vnvn(
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
double d = 0.0;
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
d += sq(v0[j] - v1[j]);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
MINLINE double len_squared_vn(
|
||||
const double v0[], const uint dims)
|
||||
{
|
||||
double d = 0.0;
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
d += sq(v0[j]);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
MINLINE double len_vnvn(
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
return sqrt(len_squared_vnvn(v0, v1, dims));
|
||||
}
|
||||
|
||||
MINLINE double len_vn(
|
||||
const double v0[], const uint dims)
|
||||
{
|
||||
return sqrt(len_squared_vn(v0, dims));
|
||||
}
|
||||
|
||||
/* Special case: save us negating a copy, then getting the length. */
|
||||
MINLINE double len_squared_negated_vnvn(
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
double d = 0.0;
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
d += sq(v0[j] + v1[j]);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
MINLINE double len_negated_vnvn(
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
return sqrt(len_squared_negated_vnvn(v0, v1, dims));
|
||||
}
|
||||
|
||||
MINLINE double normalize_vn(
|
||||
double v0[], const uint dims)
|
||||
{
|
||||
double d = len_squared_vn(v0, dims);
|
||||
if (d != 0.0 && ((d = sqrt(d)) != 0.0)) {
|
||||
imul_vn_fl(v0, 1.0 / d, dims);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/* `v_out = (v0 - v1).normalized()`. */
|
||||
MINLINE double normalize_vn_vnvn(
|
||||
double v_out[],
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
double d = 0.0;
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
double a = v0[j] - v1[j];
|
||||
d += sq(a);
|
||||
v_out[j] = a;
|
||||
}
|
||||
if (d != 0.0 && ((d = sqrt(d)) != 0.0)) {
|
||||
imul_vn_fl(v_out, 1.0 / d, dims);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
MINLINE bool is_almost_zero_ex(double val, double eps)
|
||||
{
|
||||
return (-eps < val) && (val < eps);
|
||||
}
|
||||
|
||||
MINLINE bool is_almost_zero(double val)
|
||||
{
|
||||
return is_almost_zero_ex(val, 1e-8);
|
||||
}
|
||||
|
||||
MINLINE bool equals_vnvn(
|
||||
const double v0[], const double v1[], const uint dims)
|
||||
{
|
||||
for (uint j = 0; j < dims; j++) {
|
||||
if (v0[j] != v1[j]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MINLINE void project_vn_vnvn(
|
||||
double v_out[], const double p[], const double v_proj[], const uint dims)
|
||||
{
|
||||
const double mul = dot_vnvn(p, v_proj, dims) / dot_vnvn(v_proj, v_proj, dims);
|
||||
mul_vnvn_fl(v_out, v_proj, mul, dims);
|
||||
}
|
||||
|
||||
MINLINE void project_vn_vnvn_normalized(
|
||||
double v_out[], const double p[], const double v_proj[], const uint dims)
|
||||
{
|
||||
const double mul = dot_vnvn(p, v_proj, dims);
|
||||
mul_vnvn_fl(v_out, v_proj, mul, dims);
|
||||
}
|
||||
|
||||
MINLINE void project_plane_vn_vnvn_normalized(
|
||||
double v_out[], const double v[], const double v_plane[], const uint dims)
|
||||
{
|
||||
assert(v != v_out);
|
||||
project_vn_vnvn_normalized(v_out, v, v_plane, dims);
|
||||
sub_vn_vnvn(v_out, v, v_out, dims);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
69
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_intern.h
vendored
Normal file
69
blender-5.2.0/extern/curve_fit_nd/intern/curve_fit_intern.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Campbell Barton.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __CURVE_FIT_INTERN_H__
|
||||
#define __CURVE_FIT_INTERN_H__
|
||||
|
||||
#ifndef __CURVE_FIT_UINT_DEFINED__
|
||||
#define __CURVE_FIT_UINT_DEFINED__
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Internal header for shared declarations between curve_fit_cubic.c
|
||||
* and curve_fit_cubic_refit.c.
|
||||
*/
|
||||
|
||||
/* Split point calculation functions (implemented in curve_fit_cubic.c) */
|
||||
|
||||
#define SPLIT_POINT_INVALID ((uint)-1)
|
||||
|
||||
uint split_point_find_sign_change(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint index_l, const uint index_r,
|
||||
const uint dims);
|
||||
|
||||
uint split_point_find_max_distance(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint index_l, const uint index_r,
|
||||
const uint dims);
|
||||
|
||||
uint split_point_find_max_on_axis(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint index_l, const uint index_r,
|
||||
const double *axis,
|
||||
const uint dims);
|
||||
|
||||
uint split_point_find_inflection(
|
||||
const double *points,
|
||||
const uint points_len,
|
||||
const uint index_l, const uint index_r,
|
||||
const uint dims);
|
||||
|
||||
#endif /* __CURVE_FIT_INTERN_H__ */
|
||||
221
blender-5.2.0/extern/curve_fit_nd/intern/generic_alloc_impl.h
vendored
Normal file
221
blender-5.2.0/extern/curve_fit_nd/intern/generic_alloc_impl.h
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Blender Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file generic_alloc_impl.h
|
||||
* \ingroup curve_fit
|
||||
*
|
||||
* Simple Memory Chunking Allocator
|
||||
* ================================
|
||||
*
|
||||
* Defines need to be set:
|
||||
* - #TPOOL_IMPL_PREFIX: Prefix to use for the API.
|
||||
* - #TPOOL_ALLOC_TYPE: Struct type this pool handles.
|
||||
* - #TPOOL_STRUCT: Name for pool struct name.
|
||||
* - #TPOOL_CHUNK_SIZE: Chunk size (optional), use 64kb when not defined.
|
||||
*
|
||||
* \note #TPOOL_ALLOC_TYPE must be at least `sizeof(void *)`.
|
||||
*
|
||||
* Defines the API, uses #TPOOL_IMPL_PREFIX to prefix each function.
|
||||
*
|
||||
* - *_pool_create()
|
||||
* - *_pool_destroy()
|
||||
* - *_pool_clear()
|
||||
*
|
||||
* - *_pool_elem_alloc()
|
||||
* - *_pool_elem_calloc()
|
||||
* - *_pool_elem_free()
|
||||
*/
|
||||
|
||||
/* Check we're not building directly. */
|
||||
#if !defined(TPOOL_IMPL_PREFIX) || \
|
||||
!defined(TPOOL_ALLOC_TYPE) || \
|
||||
!defined(TPOOL_STRUCT)
|
||||
# error "This file can't be compiled directly, include in another source file"
|
||||
#endif
|
||||
|
||||
#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1 ## MACRO_ARG2
|
||||
#define _CONCAT(MACRO_ARG1, MACRO_ARG2) _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
|
||||
#define _TPOOL_PREFIX(id) _CONCAT(TPOOL_IMPL_PREFIX, _##id)
|
||||
|
||||
/* Local identifiers. */
|
||||
#define pool_create _TPOOL_PREFIX(pool_create)
|
||||
#define pool_destroy _TPOOL_PREFIX(pool_destroy)
|
||||
#define pool_clear _TPOOL_PREFIX(pool_clear)
|
||||
|
||||
#define pool_elem_alloc _TPOOL_PREFIX(pool_elem_alloc)
|
||||
#define pool_elem_calloc _TPOOL_PREFIX(pool_elem_calloc)
|
||||
#define pool_elem_free _TPOOL_PREFIX(pool_elem_free)
|
||||
|
||||
/* Private identifiers (only for this file, undefine after). */
|
||||
#define pool_alloc_chunk _TPOOL_PREFIX(pool_alloc_chunk)
|
||||
#define TPoolChunk _TPOOL_PREFIX(TPoolChunk)
|
||||
#define TPoolChunkElemFree _TPOOL_PREFIX(TPoolChunkElemFree)
|
||||
|
||||
#ifndef TPOOL_CHUNK_SIZE
|
||||
#define TPOOL_CHUNK_SIZE (1 << 16) /* 64kb */
|
||||
#define _TPOOL_CHUNK_SIZE_UNDEF
|
||||
#endif
|
||||
|
||||
#ifndef UNLIKELY
|
||||
# ifdef __GNUC__
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
# else
|
||||
# define UNLIKELY(x) (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
# define MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
|
||||
struct TPoolChunk {
|
||||
struct TPoolChunk *prev;
|
||||
unsigned int size;
|
||||
unsigned int bufsize;
|
||||
TPOOL_ALLOC_TYPE buf[0];
|
||||
};
|
||||
|
||||
struct TPoolChunkElemFree {
|
||||
struct TPoolChunkElemFree *next;
|
||||
};
|
||||
|
||||
struct TPOOL_STRUCT {
|
||||
/* Always keep at least one chunk (never NULL). */
|
||||
struct TPoolChunk *chunk;
|
||||
/* When NULL, allocate a new chunk. */
|
||||
struct TPoolChunkElemFree *free;
|
||||
};
|
||||
|
||||
/**
|
||||
* Number of elems to include per #TPoolChunk when no reserved size is passed,
|
||||
* or we allocate past the reserved number.
|
||||
*
|
||||
* \note Optimize number for 64kb allocs.
|
||||
*/
|
||||
#define _TPOOL_CHUNK_DEFAULT_NUM \
|
||||
(((1 << 16) - sizeof(struct TPoolChunk)) / sizeof(TPOOL_ALLOC_TYPE))
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Internal Memory Management
|
||||
* \{ */
|
||||
|
||||
static struct TPoolChunk *pool_alloc_chunk(
|
||||
unsigned int tot_elems, struct TPoolChunk *chunk_prev)
|
||||
{
|
||||
struct TPoolChunk *chunk = malloc(
|
||||
sizeof(struct TPoolChunk) + (sizeof(TPOOL_ALLOC_TYPE) * tot_elems));
|
||||
chunk->prev = chunk_prev;
|
||||
chunk->bufsize = tot_elems;
|
||||
chunk->size = 0;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
static TPOOL_ALLOC_TYPE *pool_elem_alloc(struct TPOOL_STRUCT *pool)
|
||||
{
|
||||
TPOOL_ALLOC_TYPE *elem;
|
||||
|
||||
if (pool->free) {
|
||||
elem = (TPOOL_ALLOC_TYPE *)pool->free;
|
||||
pool->free = pool->free->next;
|
||||
}
|
||||
else {
|
||||
struct TPoolChunk *chunk = pool->chunk;
|
||||
if (UNLIKELY(chunk->size == chunk->bufsize)) {
|
||||
chunk = pool->chunk = pool_alloc_chunk(_TPOOL_CHUNK_DEFAULT_NUM, chunk);
|
||||
}
|
||||
elem = &chunk->buf[chunk->size++];
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
MAYBE_UNUSED
|
||||
static TPOOL_ALLOC_TYPE *pool_elem_calloc(struct TPOOL_STRUCT *pool)
|
||||
{
|
||||
TPOOL_ALLOC_TYPE *elem = pool_elem_alloc(pool);
|
||||
memset(elem, 0, sizeof(*elem));
|
||||
return elem;
|
||||
}
|
||||
|
||||
static void pool_elem_free(struct TPOOL_STRUCT *pool, TPOOL_ALLOC_TYPE *elem)
|
||||
{
|
||||
struct TPoolChunkElemFree *elem_free = (struct TPoolChunkElemFree *)elem;
|
||||
elem_free->next = pool->free;
|
||||
pool->free = elem_free;
|
||||
}
|
||||
|
||||
static void pool_create(struct TPOOL_STRUCT *pool, unsigned int tot_reserve)
|
||||
{
|
||||
pool->chunk = pool_alloc_chunk((tot_reserve > 1) ? tot_reserve : _TPOOL_CHUNK_DEFAULT_NUM, NULL);
|
||||
pool->free = NULL;
|
||||
}
|
||||
|
||||
MAYBE_UNUSED
|
||||
static void pool_clear(struct TPOOL_STRUCT *pool)
|
||||
{
|
||||
/* Remove all except the last chunk. */
|
||||
while (pool->chunk->prev) {
|
||||
struct TPoolChunk *chunk_prev = pool->chunk->prev;
|
||||
free(pool->chunk);
|
||||
pool->chunk = chunk_prev;
|
||||
}
|
||||
pool->chunk->size = 0;
|
||||
pool->free = NULL;
|
||||
}
|
||||
|
||||
static void pool_destroy(struct TPOOL_STRUCT *pool)
|
||||
{
|
||||
struct TPoolChunk *chunk = pool->chunk;
|
||||
do {
|
||||
struct TPoolChunk *chunk_prev;
|
||||
chunk_prev = chunk->prev;
|
||||
free(chunk);
|
||||
chunk = chunk_prev;
|
||||
} while (chunk);
|
||||
|
||||
pool->chunk = NULL;
|
||||
pool->free = NULL;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
#undef _TPOOL_CHUNK_DEFAULT_NUM
|
||||
#undef _CONCAT_AUX
|
||||
#undef _CONCAT
|
||||
#undef _TPOOL_PREFIX
|
||||
|
||||
#undef TPoolChunk
|
||||
#undef TPoolChunkElemFree
|
||||
|
||||
#ifdef _TPOOL_CHUNK_SIZE_UNDEF
|
||||
# undef TPOOL_CHUNK_SIZE
|
||||
# undef _TPOOL_CHUNK_SIZE_UNDEF
|
||||
#endif
|
||||
311
blender-5.2.0/extern/curve_fit_nd/intern/generic_heap.c
vendored
Normal file
311
blender-5.2.0/extern/curve_fit_nd/intern/generic_heap.c
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Blender Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** \file generic_heap.c
|
||||
* \ingroup curve_fit
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "generic_heap.h"
|
||||
|
||||
/* Swap with a temp value. */
|
||||
#define SWAP_TVAL(tval, a, b) { \
|
||||
(tval) = (a); \
|
||||
(a) = (b); \
|
||||
(b) = (tval); \
|
||||
} (void)0
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
# define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
struct HeapNode {
|
||||
void *ptr;
|
||||
double value;
|
||||
uint index;
|
||||
};
|
||||
|
||||
/* heap_* pool allocator. */
|
||||
#define TPOOL_IMPL_PREFIX heap
|
||||
#define TPOOL_ALLOC_TYPE HeapNode
|
||||
#define TPOOL_STRUCT HeapMemPool
|
||||
#include "generic_alloc_impl.h"
|
||||
#undef TPOOL_IMPL_PREFIX
|
||||
#undef TPOOL_ALLOC_TYPE
|
||||
#undef TPOOL_STRUCT
|
||||
|
||||
struct Heap {
|
||||
uint size;
|
||||
uint bufsize;
|
||||
HeapNode **tree;
|
||||
|
||||
struct HeapMemPool pool;
|
||||
};
|
||||
|
||||
/** \name Internal Functions
|
||||
* \{ */
|
||||
|
||||
#define HEAP_PARENT(i) (((i) - 1) >> 1)
|
||||
#define HEAP_LEFT(i) (((i) << 1) + 1)
|
||||
#define HEAP_RIGHT(i) (((i) << 1) + 2)
|
||||
/* Compare by value, using index as tie-breaker for deterministic ordering.
|
||||
* Otherwise equal values would have arbitrary ordering based on the heap's internal state.
|
||||
* While technically deterministic, this is less stable as minor changes to the heap contents
|
||||
* can yield different results elsewhere in the heap. */
|
||||
#define HEAP_COMPARE(a, b) \
|
||||
(((a)->value < (b)->value) || \
|
||||
(((a)->value == (b)->value) && ((a)->index < (b)->index)))
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
#define HEAP_EQUALS(a, b) ((a)->value == (b)->value)
|
||||
#endif
|
||||
|
||||
static void heap_swap(Heap *heap, const uint i, const uint j)
|
||||
{
|
||||
|
||||
#if 0
|
||||
SWAP(uint, heap->tree[i]->index, heap->tree[j]->index);
|
||||
SWAP(HeapNode *, heap->tree[i], heap->tree[j]);
|
||||
#else
|
||||
HeapNode **tree = heap->tree;
|
||||
union {
|
||||
uint index;
|
||||
HeapNode *node;
|
||||
} tmp;
|
||||
SWAP_TVAL(tmp.index, tree[i]->index, tree[j]->index);
|
||||
SWAP_TVAL(tmp.node, tree[i], tree[j]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void heap_down(Heap *heap, uint i)
|
||||
{
|
||||
/* Size won't change in the loop. */
|
||||
const uint size = heap->size;
|
||||
|
||||
while (1) {
|
||||
const uint l = HEAP_LEFT(i);
|
||||
const uint r = HEAP_RIGHT(i);
|
||||
uint smallest;
|
||||
|
||||
smallest = ((l < size) && HEAP_COMPARE(heap->tree[l], heap->tree[i])) ? l : i;
|
||||
|
||||
if ((r < size) && HEAP_COMPARE(heap->tree[r], heap->tree[smallest])) {
|
||||
smallest = r;
|
||||
}
|
||||
|
||||
if (smallest == i) {
|
||||
break;
|
||||
}
|
||||
|
||||
heap_swap(heap, i, smallest);
|
||||
i = smallest;
|
||||
}
|
||||
}
|
||||
|
||||
static void heap_up(Heap *heap, uint i)
|
||||
{
|
||||
while (i > 0) {
|
||||
const uint p = HEAP_PARENT(i);
|
||||
|
||||
if (HEAP_COMPARE(heap->tree[p], heap->tree[i])) {
|
||||
break;
|
||||
}
|
||||
heap_swap(heap, p, i);
|
||||
i = p;
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/** \name Public Heap API
|
||||
* \{ */
|
||||
|
||||
/* Use when the size of the heap is known in advance. */
|
||||
Heap *HEAP_new(uint tot_reserve)
|
||||
{
|
||||
Heap *heap = malloc(sizeof(Heap));
|
||||
/* Ensure we have at least one so we can keep doubling it. */
|
||||
heap->size = 0;
|
||||
heap->bufsize = tot_reserve ? tot_reserve : 1;
|
||||
heap->tree = malloc(heap->bufsize * sizeof(HeapNode *));
|
||||
|
||||
heap_pool_create(&heap->pool, tot_reserve);
|
||||
|
||||
return heap;
|
||||
}
|
||||
|
||||
void HEAP_free(Heap *heap, HeapFreeFP ptrfreefp)
|
||||
{
|
||||
if (ptrfreefp) {
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < heap->size; i++) {
|
||||
ptrfreefp(heap->tree[i]->ptr);
|
||||
}
|
||||
}
|
||||
|
||||
heap_pool_destroy(&heap->pool);
|
||||
|
||||
free(heap->tree);
|
||||
free(heap);
|
||||
}
|
||||
|
||||
void HEAP_clear(Heap *heap, HeapFreeFP ptrfreefp)
|
||||
{
|
||||
if (ptrfreefp) {
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < heap->size; i++) {
|
||||
ptrfreefp(heap->tree[i]->ptr);
|
||||
}
|
||||
}
|
||||
heap->size = 0;
|
||||
|
||||
heap_pool_clear(&heap->pool);
|
||||
}
|
||||
|
||||
HeapNode *HEAP_insert(Heap *heap, double value, void *ptr)
|
||||
{
|
||||
HeapNode *node;
|
||||
|
||||
if (UNLIKELY(heap->size >= heap->bufsize)) {
|
||||
heap->bufsize *= 2;
|
||||
heap->tree = realloc(heap->tree, heap->bufsize * sizeof(*heap->tree));
|
||||
}
|
||||
|
||||
node = heap_pool_elem_alloc(&heap->pool);
|
||||
|
||||
node->ptr = ptr;
|
||||
node->value = value;
|
||||
node->index = heap->size;
|
||||
|
||||
heap->tree[node->index] = node;
|
||||
|
||||
heap->size++;
|
||||
|
||||
heap_up(heap, node->index);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void HEAP_insert_or_update(Heap *heap, HeapNode **node_p, double value, void *ptr)
|
||||
{
|
||||
if (*node_p == NULL) {
|
||||
*node_p = HEAP_insert(heap, value, ptr);
|
||||
}
|
||||
else {
|
||||
HEAP_node_value_update_ptr(heap, *node_p, value, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool HEAP_is_empty(const Heap *heap)
|
||||
{
|
||||
return (heap->size == 0);
|
||||
}
|
||||
|
||||
uint HEAP_size(const Heap *heap)
|
||||
{
|
||||
return heap->size;
|
||||
}
|
||||
|
||||
HeapNode *HEAP_top(Heap *heap)
|
||||
{
|
||||
return heap->tree[0];
|
||||
}
|
||||
|
||||
double HEAP_top_value(const Heap *heap)
|
||||
{
|
||||
return heap->tree[0]->value;
|
||||
}
|
||||
|
||||
void *HEAP_popmin(Heap *heap)
|
||||
{
|
||||
void *ptr = heap->tree[0]->ptr;
|
||||
|
||||
assert(heap->size != 0);
|
||||
|
||||
heap_pool_elem_free(&heap->pool, heap->tree[0]);
|
||||
|
||||
if (--heap->size) {
|
||||
heap_swap(heap, 0, heap->size);
|
||||
heap_down(heap, 0);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void HEAP_remove(Heap *heap, HeapNode *node)
|
||||
{
|
||||
uint i = node->index;
|
||||
|
||||
assert(heap->size != 0);
|
||||
|
||||
while (i > 0) {
|
||||
uint p = HEAP_PARENT(i);
|
||||
|
||||
heap_swap(heap, p, i);
|
||||
i = p;
|
||||
}
|
||||
|
||||
HEAP_popmin(heap);
|
||||
}
|
||||
|
||||
void HEAP_node_value_update(Heap *heap, HeapNode *node, double value)
|
||||
{
|
||||
assert(heap->size != 0);
|
||||
if (node->value == value) {
|
||||
return;
|
||||
}
|
||||
node->value = value;
|
||||
/* Can be called in either order, makes no difference. */
|
||||
heap_up(heap, node->index);
|
||||
heap_down(heap, node->index);
|
||||
}
|
||||
|
||||
void HEAP_node_value_update_ptr(Heap *heap, HeapNode *node, double value, void *ptr)
|
||||
{
|
||||
node->ptr = ptr;
|
||||
HEAP_node_value_update(heap, node, value);
|
||||
}
|
||||
|
||||
double HEAP_node_value(const HeapNode *node)
|
||||
{
|
||||
return node->value;
|
||||
}
|
||||
|
||||
void *HEAP_node_ptr(HeapNode *node)
|
||||
{
|
||||
return node->ptr;
|
||||
}
|
||||
57
blender-5.2.0/extern/curve_fit_nd/intern/generic_heap.h
vendored
Normal file
57
blender-5.2.0/extern/curve_fit_nd/intern/generic_heap.h
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Blender Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __GENERIC_HEAP_H__
|
||||
#define __GENERIC_HEAP_H__
|
||||
|
||||
/** \file generic_heap.h
|
||||
* \ingroup curve_fit
|
||||
*/
|
||||
|
||||
struct Heap;
|
||||
struct HeapNode;
|
||||
typedef struct Heap Heap;
|
||||
typedef struct HeapNode HeapNode;
|
||||
|
||||
typedef void (*HeapFreeFP)(void *ptr);
|
||||
|
||||
Heap *HEAP_new(unsigned int tot_reserve);
|
||||
bool HEAP_is_empty(const Heap *heap);
|
||||
void HEAP_free(Heap *heap, HeapFreeFP ptrfreefp);
|
||||
void *HEAP_node_ptr(HeapNode *node);
|
||||
void HEAP_remove(Heap *heap, HeapNode *node);
|
||||
HeapNode *HEAP_insert(Heap *heap, double value, void *ptr);
|
||||
void HEAP_insert_or_update(Heap *heap, HeapNode **node_p, double value, void *ptr);
|
||||
void *HEAP_popmin(Heap *heap);
|
||||
void HEAP_clear(Heap *heap, HeapFreeFP ptrfreefp);
|
||||
unsigned int HEAP_size(const Heap *heap);
|
||||
HeapNode *HEAP_top(Heap *heap);
|
||||
double HEAP_top_value(const Heap *heap);
|
||||
void HEAP_node_value_update(Heap *heap, HeapNode *node, double value);
|
||||
void HEAP_node_value_update_ptr(Heap *heap, HeapNode *node, double value, void *ptr);
|
||||
double HEAP_node_value(const HeapNode *node);
|
||||
|
||||
#endif /* __GENERIC_HEAP_H__ */
|
||||
Reference in New Issue
Block a user