70 for (
int i = 0; i < target->
path_len; i++) {
98 short handle_type = (handle_1) ? point->
h1 : point->
h2;
99 float *handle_location = (handle_1) ? &point->
h1_loc[0] : &point->
h2_loc[0];
101 float start_position[2];
110 handle_location[0] += delta ? delta[0] : 0.0f;
111 handle_location[1] += delta ? delta[1] : 0.0f;
113 handle_location[0] = 0.125f * roundf(8.0f * handle_location[0]);
114 handle_location[1] = 0.125f * roundf(8.0f * handle_location[1]);
119 short other_handle_type = (handle_1) ? point->
h2 : point->
h1;
121 float *other_handle_location = (handle_1) ? &point->
h2_loc[0] : &point->
h1_loc[0];
122 other_handle_location[0] = 2.0f * point->
x - handle_location[0];
123 other_handle_location[1] = 2.0f * point->
y - handle_location[1];
127 if (!
equals_v2v2(handle_location, start_position)) {
144 const float delta[2])
151 if (point == profile->
path) {
154 float origx = point->
x;
155 float origy = point->
y;
157 point->
x += delta[0];
158 point->
y += delta[1];
160 point->
x = 0.125f * roundf(8.0f * point->
x);
161 point->
y = 0.125f * roundf(8.0f * point->
y);
174 point->
h1_loc[0] += point->
x - origx;
175 point->
h1_loc[1] += point->
y - origy;
178 point->
h2_loc[0] += point->
x - origx;
179 point->
h2_loc[1] += point->
y - origy;
182 if (point->
x != origx || point->
y != origy) {
200 if (!(point > profile->
path && point < profile->path + profile->
path_len)) {
207 int i_delete = (int)(point - profile->
path);
212 memcpy(new_path + i_delete,
213 profile->
path + i_delete + 1,
217 profile->
path = new_path;
239 new_path[0] = profile->
path[0];
240 for (; i_old < profile->
path_len - 1; i_old++) {
241 if (!(profile->
path[i_old].
flag & flag)) {
242 new_path[i_new] = profile->
path[i_old];
249 new_path[i_new] = profile->
path[i_old];
252 profile->
path = new_path;
277 const float new_loc[2] = {
x,
y};
285 float min_distance = FLT_MAX;
287 for (
int i = 0; i < profile->
path_len - 1; i++) {
288 const float loc1[2] = {profile->
path[i].
x, profile->
path[i].
y};
289 const float loc2[2] = {profile->
path[i + 1].
x, profile->
path[i + 1].
y};
303 for (
int i_new = 0, i_old = 0; i_new < profile->
path_len; i_new++) {
304 if (i_new != i_insert) {
306 new_path[i_new] = profile->
path[i_old];
313 char new_handle_type = (new_path[i_new - 1].
h2 ==
HD_VECT &&
318 new_pt = &new_path[i_new];
326 profile->
path = new_path;
337 for (
int i = 0; i < profile->
path_len; i++) {
339 profile->
path[i].
h1 = type_1;
340 profile->
path[i].
h2 = type_2;
371 for (
int i = 0; i < profile->
path_len; i++) {
372 int i_reversed = profile->
path_len - i - 1;
375 new_path[i_reversed].
profile = profile;
390 profile->
path = new_path;
402 for (
int i = 1; i < n - 2; i++) {
403 const float x = 1.0f - (0.5f * (1.0f -
cosf((
float)((i / (
float)(n - 3))) *
M_PI_2)));
404 const float y = 0.5f + 0.5f *
sinf((
float)((i / (
float)(n - 3)) *
M_PI_2));
426 float n_steps_x = (n % 2 == 0) ? n : (n - 1);
427 float n_steps_y = (n % 2 == 0) ? (n - 2) : (n - 1);
429 for (
int i = 0; i < n; i++) {
430 int step_x = (i + 1) / 2;
432 const float x = 1.0f - ((
float)(2 * step_x) / n_steps_x);
433 const float y = (
float)(2 * step_y) / n_steps_y;
534 for (
int i = 0; i < profile->
path_len; i++) {
563 float *point_loc = &point->
x;
566 const float *prev_loc, *next_loc;
569 pt[0] = 2.0f * point_loc[0] - next_loc[0];
570 pt[1] = 2.0f * point_loc[1] - next_loc[1];
579 pt[0] = 2.0f * point_loc[0] - prev_loc[0];
580 pt[1] = 2.0f * point_loc[1] - prev_loc[1];
587 float dvec_a[2], dvec_b[2];
591 float len_a =
len_v2(dvec_a);
592 float len_b =
len_v2(dvec_b);
602 tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
603 tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
629 for (
int i = 1; i < path_len - 1; i++) {
644 float start_handle_direction[2], end_handle_direction[2];
646 sub_v2_v2v2(start_handle_direction, path[i_edge].h2_loc, &path[i_edge].
x);
648 sub_v2_v2v2(end_handle_direction, &path[i_edge + 1].
x, path[i_edge + 1].h1_loc);
650 return angle_v2v2(start_handle_direction, end_handle_direction);
691 bool sample_straight_edges,
698 int totedges = totpoints - 1;
705 for (
int i = 0; i < totedges; i++) {
716 if (n_segments >= totedges) {
717 if (sample_straight_edges) {
720 int n_common = n_segments / totedges;
721 n_left = n_segments % totedges;
726 for (
int i = 0; i < totedges; i++) {
727 n_samples[i] = n_common;
734 int n_curved_edges = 0;
735 for (
int i = 0; i < totedges; i++) {
741 n_curved_edges = (n_curved_edges == 0) ? totedges : n_curved_edges;
744 n_left = n_segments - (totedges - n_curved_edges);
745 int n_common = n_left / n_curved_edges;
747 for (
int i = 0; i < totedges; i++) {
751 n_samples[i] += n_common;
760 n_left -= n_common * n_curved_edges;
769 for (
int i = 0; i < n_left; i++) {
778 for (
int i_sample = 0, i = 0; i < totedges; i++) {
779 if (n_samples[i] > 0) {
781 r_samples[i_sample].
h1 = path[i].
h1;
782 r_samples[i_sample].
h2 = path[i].
h2;
784 for (
int j = i_sample + 1; j < i_sample + n_samples[i]; j++) {
785 r_samples[j].
flag = 0;
794 path[i + 1].h1_loc[0],
796 &r_samples[i_sample].
x,
801 path[i + 1].h1_loc[1],
803 &r_samples[i_sample].
y,
807 i_sample += n_samples[i];
827 new_table[n_samples - 1].
x = 0.0f;
828 new_table[n_samples - 1].
y = 1.0f;
831 profile->
table = new_table;
841 if (n_samples <= 0) {
874 profile->
path[0].
x = 1.0f;
875 profile->
path[0].
y = 0.0f;
877 profile->
path[1].
x = 1.0f;
878 profile->
path[1].
y = 1.0f;
916 for (
int i = 0; i < profile->
path_len; i++) {
938 for (
int i = 0; i < profile->
path_len - 1; i++) {
997 float total_length = 0;
1001 return total_length;
1017 const float segment_length = total_length / n_segments;
1018 float length_travelled = 0.0f;
1020 float distance_to_previous_table_point = 0.0f;
1024 r_samples[0].
x = profile->
table[0].
x;
1025 r_samples[0].
y = profile->
table[0].
y;
1028 float segment_left = segment_length;
1029 for (
int i = 1; i < n_segments; i++) {
1031 while (distance_to_next_table_point < segment_left) {
1032 length_travelled += distance_to_next_table_point;
1033 segment_left -= distance_to_next_table_point;
1036 distance_to_previous_table_point = 0.0f;
1039 float factor = (distance_to_previous_table_point + segment_left) /
1040 (distance_to_previous_table_point + distance_to_next_table_point);
1043 BLI_assert(factor <= 1.0f && factor >= 0.0f);
1044 #ifdef DEBUG_CURVEPROFILE_EVALUATE
1045 printf(
"segment_left: %.3f\n", segment_left);
1046 printf(
"i_table: %d\n", i_table);
1047 printf(
"distance_to_previous_table_point: %.3f\n", distance_to_previous_table_point);
1048 printf(
"distance_to_next_table_point: %.3f\n", distance_to_next_table_point);
1049 printf(
"Interpolating with factor %.3f from (%.3f, %.3f) to (%.3f, %.3f)\n\n",
1051 profile->
table[i_table].
x,
1052 profile->
table[i_table].
y,
1053 profile->
table[i_table + 1].
x,
1054 profile->
table[i_table + 1].
y);
1058 distance_to_next_table_point -= segment_left;
1059 distance_to_previous_table_point += segment_left;
1060 length_travelled += segment_left;
1061 segment_left = segment_length;
1073 float length_portion,
1078 const float requested_length = length_portion * total_length;
1082 float length_travelled = 0.0f;
1083 while (length_travelled < requested_length) {
1089 if (length_travelled + new_length >= requested_length) {
1092 length_travelled += new_length;
1099 float lerp_factor = (requested_length - length_travelled) / distance_to_next_point;
1101 #ifdef DEBUG_CURVEPROFILE_EVALUATE
1102 printf(
"CURVEPROFILE EVALUATE\n");
1103 printf(
" length portion input: %f\n", (
double)length_portion);
1104 printf(
" requested path length: %f\n", (
double)requested_length);
1105 printf(
" distance to next point: %f\n", (
double)distance_to_next_point);
1106 printf(
" length travelled: %f\n", (
double)length_travelled);
1107 printf(
" lerp-factor: %f\n", (
double)lerp_factor);
1108 printf(
" ith point (%f, %f)\n", (
double)profile->
path[i].
x, (
double)profile->
path[i].
y);
1109 printf(
" next point(%f, %f)\n", (
double)profile->
path[i + 1].
x, (
double)profile->
path[i + 1].
y);
1130 for (
int i = 0; i < profile->
path_len; i++) {
typedef float(TangentPoint)[2]
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
@ PROF_UPDATE_REMOVE_DOUBLES
MINLINE float max_ff(float a, float b)
MINLINE float pow2f(float x)
MINLINE float clamp_f(float value, float min, float max)
MINLINE float min_ff(float a, float b)
MINLINE float interpf(float a, float b, float t)
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
float angle_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
@ PROF_SAMPLE_EVEN_LENGTHS
@ PROF_SAMPLE_STRAIGHT_EDGES
#define PROF_TABLE_LEN(n_pts)
_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 y
Read Guarded memory(de)allocation.
static float bezt_edge_handle_angle(const CurveProfilePoint *path, int i_edge)
void BKE_curveprofile_init(CurveProfile *profile, short segments_len)
void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile, float length_portion, float *x_out, float *y_out)
bool BKE_curveprofile_remove_point(CurveProfile *profile, CurveProfilePoint *point)
void BKE_curveprofile_copy_data(CurveProfile *target, const CurveProfile *profile)
CurveProfile * BKE_curveprofile_copy(const CurveProfile *profile)
void BKE_curveprofile_selected_handle_set(CurveProfile *profile, int type_1, int type_2)
static void curveprofile_build_steps(CurveProfile *profile)
void BKE_curveprofile_blend_read(struct BlendDataReader *reader, struct CurveProfile *profile)
static void curveprofile_build_supports(CurveProfile *profile)
float BKE_curveprofile_total_length(const CurveProfile *profile)
void BKE_curveprofile_create_samples(CurveProfile *profile, int n_segments, bool sample_straight_edges, CurveProfilePoint *r_samples)
static void curveprofile_make_table(CurveProfile *profile)
void BKE_curveprofile_reset(CurveProfile *profile)
static void calculate_path_handles(CurveProfilePoint *path, int path_len)
void BKE_curveprofile_create_samples_even_spacing(CurveProfile *profile, int n_segments, CurveProfilePoint *r_samples)
static CurveProfilePoint mirror_point(const CurveProfilePoint *point)
static bool is_curved_edge(CurveProfilePoint *path, int i)
void BKE_curveprofile_free_data(CurveProfile *profile)
void BKE_curveprofile_remove_by_flag(CurveProfile *profile, const short flag)
CurveProfilePoint * BKE_curveprofile_insert(CurveProfile *profile, float x, float y)
void BKE_curveprofile_reset_view(CurveProfile *profile)
static void point_calculate_handle(CurveProfilePoint *point, const CurveProfilePoint *prev, const CurveProfilePoint *next)
void BKE_curveprofile_reverse(CurveProfile *profile)
bool BKE_curveprofile_move_point(struct CurveProfile *profile, struct CurveProfilePoint *point, const bool snap, const float delta[2])
static void point_init(CurveProfilePoint *point, float x, float y, short flag, char h1, char h2)
bool BKE_curveprofile_move_handle(struct CurveProfilePoint *point, const bool handle_1, const bool snap, const float delta[2])
void BKE_curveprofile_blend_write(struct BlendWriter *writer, const struct CurveProfile *profile)
struct CurveProfile * BKE_curveprofile_add(eCurveProfilePresets preset)
void BKE_curveprofile_free(CurveProfile *profile)
static float curveprofile_distance_to_next_table_point(const CurveProfile *profile, int i)
void BKE_curveprofile_update(CurveProfile *profile, const int update_flags)
static int sort_points_curvature(const void *in_a, const void *in_b)
static void curveprofile_make_segments_table(CurveProfile *profile)
void BKE_curveprofile_set_defaults(CurveProfile *profile)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
vector snap(vector a, vector b)
struct CurveProfile * profile
CurveProfilePoint * table
CurveProfilePoint * segments
ccl_device_inline float distance(const float2 &a, const float2 &b)