25 #define PROF_TABLE_MAX 512
33 CurveProfile *profile = MEM_cnew<CurveProfile>(__func__);
67 for (
int i = 0; i < target->
path_len; i++) {
91 profile->
table =
nullptr;
95 for (
int i = 0; i < profile->
path_len; i++) {
111 const float delta[2])
113 short handle_type = (handle_1) ?
point->h1 :
point->h2;
114 float *handle_location = (handle_1) ? &
point->h1_loc[0] : &
point->h2_loc[0];
116 float start_position[2];
125 handle_location[0] += delta ? delta[0] : 0.0f;
126 handle_location[1] += delta ? delta[1] : 0.0f;
128 handle_location[0] = 0.125f * roundf(8.0f * handle_location[0]);
129 handle_location[1] = 0.125f * roundf(8.0f * handle_location[1]);
134 short other_handle_type = (handle_1) ?
point->h2 :
point->h1;
136 float *other_handle_location = (handle_1) ? &
point->h2_loc[0] : &
point->h1_loc[0];
137 other_handle_location[0] = 2.0f *
point->x - handle_location[0];
138 other_handle_location[1] = 2.0f *
point->y - handle_location[1];
142 if (!
equals_v2v2(handle_location, start_position)) {
151 const float delta[2])
161 float origx =
point->x;
162 float origy =
point->y;
164 point->x += delta[0];
165 point->y += delta[1];
210 int i_delete = (int)(
point - profile->
path);
215 memcpy(new_path + i_delete,
216 profile->
path + i_delete + 1,
220 profile->
path = new_path;
235 new_path[0] = profile->
path[0];
236 for (; i_old < profile->
path_len - 1; i_old++) {
238 new_path[i_new] = profile->
path[i_old];
245 new_path[i_new] = profile->
path[i_old];
248 profile->
path = new_path;
266 const float new_loc[2] = {
x,
y};
274 float min_distance = FLT_MAX;
276 for (
int i = 0; i < profile->
path_len - 1; i++) {
277 const float loc1[2] = {profile->
path[i].
x, profile->
path[i].
y};
278 const float loc2[2] = {profile->
path[i + 1].
x, profile->
path[i + 1].
y};
292 for (
int i_new = 0, i_old = 0; i_new < profile->
path_len; i_new++) {
293 if (i_new != i_insert) {
295 new_path[i_new] = profile->
path[i_old];
302 char new_handle_type = (new_path[i_new - 1].
h2 ==
HD_VECT &&
307 new_pt = &new_path[i_new];
315 profile->
path = new_path;
321 for (
int i = 0; i < profile->
path_len; i++) {
323 profile->
path[i].
h1 = type_1;
324 profile->
path[i].
h2 = type_2;
350 for (
int i = 0; i < profile->
path_len; i++) {
351 int i_reversed = profile->
path_len - i - 1;
354 new_path[i_reversed].
profile = profile;
369 profile->
path = new_path;
381 for (
int i = 1; i < n - 2; i++) {
382 const float x = 1.0f - (0.5f * (1.0f -
cosf((
float)((i / (
float)(n - 3))) *
M_PI_2)));
383 const float y = 0.5f + 0.5f *
sinf((
float)((i / (
float)(n - 3)) *
M_PI_2));
405 float n_steps_x = (n % 2 == 0) ? n : (n - 1);
406 float n_steps_y = (n % 2 == 0) ? (n - 2) : (n - 1);
408 for (
int i = 0; i < n; i++) {
409 int step_x = (i + 1) / 2;
411 const float x = 1.0f - ((
float)(2 * step_x) / n_steps_x);
412 const float y = (
float)(2 * step_y) / n_steps_y;
506 for (
int i = 0; i < profile->
path_len; i++) {
511 profile->
table =
nullptr;
523 const int resolution = 16;
550 float *point_loc = &
point->x;
553 const float *prev_loc, *next_loc;
554 if (
prev ==
nullptr) {
556 pt[0] = 2.0f * point_loc[0] - next_loc[0];
557 pt[1] = 2.0f * point_loc[1] - next_loc[1];
564 if (
next ==
nullptr) {
566 pt[0] = 2.0f * point_loc[0] - prev_loc[0];
567 pt[1] = 2.0f * point_loc[1] - prev_loc[1];
574 float dvec_a[2], dvec_b[2];
578 float len_a =
len_v2(dvec_a);
579 float len_b =
len_v2(dvec_b);
589 tvec[0] = dvec_b[0] / len_b + dvec_a[0] / len_a;
590 tvec[1] = dvec_b[1] / len_b + dvec_a[1] / len_a;
616 for (
int i = 1; i <
path_len - 1; i++) {
631 float start_handle_direction[2], end_handle_direction[2];
637 return angle_v2v2(start_handle_direction, end_handle_direction);
656 if (
a->point_curvature >
b->point_curvature) {
678 bool sample_straight_edges,
685 int totedges = totpoints - 1;
692 for (
int i = 0; i < totedges; i++) {
703 if (n_segments >= totedges) {
704 if (sample_straight_edges) {
707 int n_common = n_segments / totedges;
708 n_left = n_segments % totedges;
713 for (
int i = 0; i < totedges; i++) {
714 n_samples[i] = n_common;
721 int n_curved_edges = 0;
722 for (
int i = 0; i < totedges; i++) {
728 n_curved_edges = (n_curved_edges == 0) ? totedges : n_curved_edges;
731 n_left = n_segments - (totedges - n_curved_edges);
732 int n_common = n_left / n_curved_edges;
734 for (
int i = 0; i < totedges; i++) {
738 n_samples[i] += n_common;
747 n_left -= n_common * n_curved_edges;
756 for (
int i = 0; i < n_left; i++) {
765 for (
int i_sample = 0, i = 0; i < totedges; i++) {
766 if (n_samples[i] > 0) {
768 r_samples[i_sample].
h1 = path[i].
h1;
769 r_samples[i_sample].
h2 = path[i].
h2;
771 for (
int j = i_sample + 1; j < i_sample + n_samples[i]; j++) {
772 r_samples[j].
flag = 0;
781 path[i + 1].h1_loc[0],
783 &r_samples[i_sample].
x,
788 path[i + 1].h1_loc[1],
790 &r_samples[i_sample].
y,
794 i_sample += n_samples[i];
812 profile->
path[0].
x = 1.0f;
813 profile->
path[0].
y = 0.0f;
815 profile->
path[1].
x = 1.0f;
816 profile->
path[1].
y = 1.0f;
853 float total_length = 0;
873 const float segment_length = total_length / n_segments;
875 float distance_to_previous_table_point = 0.0f;
879 r_samples[0].
x = profile->
table[0].
x;
880 r_samples[0].
y = profile->
table[0].
y;
883 float segment_left = segment_length;
884 for (
int i = 1; i < n_segments; i++) {
886 while (distance_to_next_table_point < segment_left) {
887 segment_left -= distance_to_next_table_point;
890 distance_to_previous_table_point = 0.0f;
893 float factor = (distance_to_previous_table_point + segment_left) /
894 (distance_to_previous_table_point + distance_to_next_table_point);
898 #ifdef DEBUG_CURVEPROFILE_EVALUATE
899 printf(
"segment_left: %.3f\n", segment_left);
900 printf(
"i_table: %d\n", i_table);
901 printf(
"distance_to_previous_table_point: %.3f\n", distance_to_previous_table_point);
902 printf(
"distance_to_next_table_point: %.3f\n", distance_to_next_table_point);
903 printf(
"Interpolating with factor %.3f from (%.3f, %.3f) to (%.3f, %.3f)\n\n",
905 profile->
table[i_table].
x,
906 profile->
table[i_table].
y,
907 profile->
table[i_table + 1].
x,
908 profile->
table[i_table + 1].
y);
912 distance_to_next_table_point -= segment_left;
913 distance_to_previous_table_point += segment_left;
914 segment_left = segment_length;
933 new_table[n_samples - 1].
x = 0.0f;
934 new_table[n_samples - 1].
y = 1.0f;
937 profile->
table = new_table;
947 if (n_samples <= 0) {
976 for (
int i = 0; i < profile->
path_len; i++) {
998 for (
int i = 0; i < profile->
path_len - 1; i++) {
1021 float length_portion,
1026 const float requested_length = length_portion * total_length;
1030 float length_travelled = 0.0f;
1031 while (length_travelled < requested_length) {
1037 if (length_travelled + new_length >= requested_length) {
1040 length_travelled += new_length;
1047 float lerp_factor = (requested_length - length_travelled) / distance_to_next_point;
1049 #ifdef DEBUG_CURVEPROFILE_EVALUATE
1050 printf(
"CURVEPROFILE EVALUATE\n");
1051 printf(
" length portion input: %f\n", (
double)length_portion);
1052 printf(
" requested path length: %f\n", (
double)requested_length);
1053 printf(
" distance to next point: %f\n", (
double)distance_to_next_point);
1054 printf(
" length travelled: %f\n", (
double)length_travelled);
1055 printf(
" lerp-factor: %f\n", (
double)lerp_factor);
1056 printf(
" ith point (%f, %f)\n", (
double)profile->
path[i].
x, (
double)profile->
path[i].
y);
1057 printf(
" next point(%f, %f)\n", (
double)profile->
path[i + 1].
x, (
double)profile->
path[i + 1].
y);
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
_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.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
static float bezt_edge_handle_angle(const CurveProfilePoint *path, int i_edge)
static float curveprofile_total_length(const CurveProfile *profile)
void BKE_curveprofile_init(CurveProfile *profile, short segments_len)
static void create_samples_even_spacing(CurveProfile *profile, int n_segments, CurveProfilePoint *r_samples)
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)
static void curveprofile_make_table(CurveProfile *profile)
void BKE_curveprofile_reset(CurveProfile *profile)
static void calculate_path_handles(CurveProfilePoint *path, int path_len)
static CurveProfilePoint mirror_point(const CurveProfilePoint *point)
static bool is_curved_edge(CurveProfilePoint *path, int i)
int BKE_curveprofile_table_size(const CurveProfile *profile)
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)
static void create_samples(CurveProfile *profile, int n_segments, bool sample_straight_edges, CurveProfilePoint *r_samples)
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)
T clamp(const T &a, const T &min, const T &max)
T distance(const T &a, const T &b)
SymEdge< T > * prev(const SymEdge< T > *se)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
vector snap(vector a, vector b)
struct CurveProfile * profile
CurveProfilePoint * table
CurveProfilePoint * segments