Curve Fitting: Add alternate 'refit' method
[blender.git] / extern / curve_fit_nd / curve_fit_nd.h
1 /*
2  * Copyright (c) 2016, DWANGO Co., Ltd.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the <organization> nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef __CURVE_FIT_ND_H__
29 #define __CURVE_FIT_ND_H__
30
31 /** \file curve_fit_nd.h
32  *  \ingroup curve_fit
33  */
34
35
36 /* curve_fit_cubic.c */
37
38 /**
39  * Takes a flat array of points and evalues that to calculate a bezier spline.
40  *
41  * \param points, points_len: The array of points to calculate a cubics from.
42  * \param dims: The number of dimensions for for each element in \a points.
43  * \param error_threshold: the error threshold to allow for,
44  * the curve will be within this distance from \a points.
45  * \param corners, corners_len: indices for points which will not have aligned tangents (optional).
46  * This can use the output of #curve_fit_corners_detect_db which has been included
47  * to evaluate a line to detect corner indices.
48  *
49  * \param r_cubic_array, r_cubic_array_len: Resulting array of tangents and knots, formatted as follows:
50  * ``r_cubic_array[r_cubic_array_len][3][dims]``,
51  * where each point has 0 and 2 for the tangents and the middle index 1 for the knot.
52  * The size of the *flat* array will be ``r_cubic_array_len * 3 * dims``.
53  * \param r_corner_index_array, r_corner_index_len: Corner indices in in \a r_cubic_array (optional).
54  * This allows you to access corners on the resulting curve.
55  *
56  * \returns zero on success, nonzero is reserved for error values.
57  */
58 int curve_fit_cubic_to_points_db(
59         const double       *points,
60         const unsigned int  points_len,
61         const unsigned int  dims,
62         const double        error_threshold,
63         const unsigned int  calc_flag,
64         const unsigned int *corners,
65         unsigned int        corners_len,
66
67         double **r_cubic_array, unsigned int *r_cubic_array_len,
68         unsigned int **r_cubic_orig_index,
69         unsigned int **r_corner_index_array, unsigned int *r_corner_index_len);
70
71 int curve_fit_cubic_to_points_fl(
72         const float        *points,
73         const unsigned int  points_len,
74         const unsigned int  dims,
75         const float         error_threshold,
76         const unsigned int  calc_flag,
77         const unsigned int *corners,
78         const unsigned int  corners_len,
79
80         float **r_cubic_array, unsigned int *r_cubic_array_len,
81         unsigned int **r_cubic_orig_index,
82         unsigned int **r_corners_index_array, unsigned int *r_corners_index_len);
83
84 /**
85  * Takes a flat array of points and evalues that to calculate handle lengths.
86  *
87  * \param points, points_len: The array of points to calculate a cubics from.
88  * \param dims: The number of dimensions for for each element in \a points.
89  * \param points_length_cache: Optional pre-calculated lengths between points.
90  * \param error_threshold: the error threshold to allow for,
91  * \param tan_l, tan_r: Normalized tangents the handles will be aligned to.
92  * Note that tangents must both point along the direction of the \a points,
93  * so \a tan_l points in the same direction of the resulting handle,
94  * where \a tan_r will point the opposite direction of its handle.
95  *
96  * \param r_handle_l, r_handle_r: Resulting calculated handles.
97  * \param r_error_sq: The maximum distance  (squared) this curve diverges from \a points.
98  */
99 int curve_fit_cubic_to_points_single_db(
100         const double      *points,
101         const unsigned int points_len,
102         const double      *points_length_cache,
103         const unsigned int dims,
104         const double       error_threshold,
105         const double       tan_l[],
106         const double       tan_r[],
107
108         double  r_handle_l[],
109         double  r_handle_r[],
110         double *r_error_sq);
111
112 int curve_fit_cubic_to_points_single_fl(
113         const float       *points,
114         const unsigned int points_len,
115         const float       *points_length_cache,
116         const unsigned int dims,
117         const float        error_threshold,
118         const float        tan_l[],
119         const float        tan_r[],
120
121         float   r_handle_l[],
122         float   r_handle_r[],
123         float  *r_error_sq);
124
125 enum {
126         CURVE_FIT_CALC_HIGH_QUALIY          = (1 << 0),
127         CURVE_FIT_CALC_CYCLIC               = (1 << 1),
128 };
129
130
131 /* curve_fit_cubic_refit.c */
132
133 int curve_fit_cubic_to_points_refit_db(
134         const double         *points,
135         const unsigned int    points_len,
136         const unsigned int    dims,
137         const double          error_threshold,
138         const unsigned int    calc_flag,
139         const unsigned int   *corners,
140         unsigned int          corners_len,
141         const double          corner_angle,
142
143         double **r_cubic_array, unsigned int *r_cubic_array_len,
144         unsigned int   **r_cubic_orig_index,
145         unsigned int   **r_corner_index_array, unsigned int *r_corner_index_len);
146
147 int curve_fit_cubic_to_points_refit_fl(
148         const float          *points,
149         const unsigned int    points_len,
150         const unsigned int    dims,
151         const float           error_threshold,
152         const unsigned int    calc_flag,
153         const unsigned int   *corners,
154         unsigned int          corners_len,
155         const float           corner_angle,
156
157         float **r_cubic_array, unsigned int *r_cubic_array_len,
158         unsigned int   **r_cubic_orig_index,
159         unsigned int   **r_corner_index_array, unsigned int *r_corner_index_len);
160
161 /* curve_fit_corners_detect.c */
162
163 /**
164  * A helper function that takes a line and outputs its corner indices.
165  *
166  * \param points, points_len: Curve to evaluate.
167  * \param dims: The number of dimensions for for each element in \a points.
168  * \param radius_min: Corners on the curve between points below this radius are ignored.
169  * \param radius_max: Corners on the curve above this radius are ignored.
170  * \param samples_max: Prevent testing corners beyond this many points
171  * (prevents a large radius taking excessive time to compute).
172  * \param angle_threshold: Angles above this value are considered corners
173  * (higher value for fewer corners).
174  *
175  * \param r_corners, r_corners_len: Resulting array of corners.
176  *
177  * \returns zero on success, nonzero is reserved for error values.
178  */
179 int curve_fit_corners_detect_db(
180         const double      *points,
181         const unsigned int points_len,
182         const unsigned int dims,
183         const double       radius_min,
184         const double       radius_max,
185         const unsigned int samples_max,
186         const double       angle_threshold,
187
188         unsigned int **r_corners,
189         unsigned int  *r_corners_len);
190
191 int curve_fit_corners_detect_fl(
192         const float       *points,
193         const unsigned int points_len,
194         const unsigned int dims,
195         const float        radius_min,
196         const float        radius_max,
197         const unsigned int samples_max,
198         const float        angle_threshold,
199
200         unsigned int **r_corners,
201         unsigned int  *r_corners_len);
202
203 #endif  /* __CURVE_FIT_ND_H__ */