[Bf-blender-cvs] [51a699ba78d] soc-2019-bevel-profiles: Profile Widget: Even length sampling option
Hans Goudey
noreply at git.blender.org
Sat Aug 17 22:49:50 CEST 2019
Commit: 51a699ba78d4c5236c31a6b81b50c56d85023f02
Author: Hans Goudey
Date: Sat Aug 17 16:48:58 2019 -0400
Branches: soc-2019-bevel-profiles
https://developer.blender.org/rB51a699ba78d4c5236c31a6b81b50c56d85023f02
Profile Widget: Even length sampling option
Not compatible with !sample_straight_edges, but it's helpful
enought that it's worthwhile to include now.
===================================================================
M source/blender/blenkernel/BKE_profile_widget.h
M source/blender/blenkernel/intern/profile_widget.c
M source/blender/editors/interface/interface_templates.c
M source/blender/makesdna/DNA_profilewidget_types.h
M source/blender/makesrna/intern/rna_profile.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_profile_widget.h b/source/blender/blenkernel/BKE_profile_widget.h
index 13f9cc332a8..c5358b3dbd7 100644
--- a/source/blender/blenkernel/BKE_profile_widget.h
+++ b/source/blender/blenkernel/BKE_profile_widget.h
@@ -64,9 +64,9 @@ void BKE_profilewidget_changed(struct ProfileWidget *prwdgt, const bool rem_doub
/* Need to find the total length of the curve to sample a portion of it */
float BKE_profilewidget_total_length(const struct ProfileWidget *prwdgt);
-void BKE_profilewidget_create_samples_even_spacing(const struct ProfileWidget *prwdgt,
- double *x_table_out,
- double *y_table_out);
+void BKE_profilewidget_create_samples_even_spacing(struct ProfileWidget *prwdgt,
+ int n_segments,
+ struct ProfilePoint *r_samples);
/* Length portion is the fraction of the total path length where we want the location */
void BKE_profilewidget_evaluate_length_portion(const struct ProfileWidget *prwdgt,
diff --git a/source/blender/blenkernel/intern/profile_widget.c b/source/blender/blenkernel/intern/profile_widget.c
index 1077f9efe82..6afe87c8ffb 100644
--- a/source/blender/blenkernel/intern/profile_widget.c
+++ b/source/blender/blenkernel/intern/profile_widget.c
@@ -41,8 +41,6 @@
#include "BKE_curve.h"
#include "BKE_fcurve.h"
-#define DEBUG_PRWDGT_EVALUATE
-
void BKE_profilewidget_free_data(ProfileWidget *prwdgt)
{
if (prwdgt->path) {
@@ -508,11 +506,6 @@ static float bezt_edge_handle_angle(const BezTriple *bezt, int i_edge)
sub_v2_v2v2(end_handle_direction, bezt[i_edge + 1].vec[1], bezt[i_edge + 1].vec[0]);
float angle = angle_v2v2(start_handle_direction, end_handle_direction);
-// printf("bezt_edge_handle_angle: i: %d, angle:%.2f\n", i_edge, RAD2DEGF(angle));
-// printf(" first point: (%.2f, %.2f)\n", bezt[i_edge].vec[1][0], bezt[i_edge].vec[1][1]);
-// printf(" first inner handle: (%.2f, %.2f)\n", bezt[i_edge].vec[2][0], bezt[i_edge].vec[2][1]);
-// printf(" second inner handle: (%.2f, %.2f)\n", bezt[i_edge + 1].vec[0][0], bezt[i_edge + 1].vec[0][1]);
-// printf(" second point: (%.2f, %.2f)\n", bezt[i_edge + 1].vec[1][0], bezt[i_edge + 1].vec[1][1]);
return angle;
}
@@ -745,13 +738,20 @@ static void profilewidget_make_segments_table(ProfileWidget *prwdgt)
ProfilePoint *new_table = MEM_callocN((size_t)(n_samples + 1) * sizeof(ProfilePoint),
"samples table");
- BKE_profilewidget_create_samples(prwdgt, n_samples, prwdgt->flag & PROF_SAMPLE_STRAIGHT_EDGES,
- new_table);
+ if (prwdgt->flag & PROF_SAMPLE_EVEN_LENGTHS) {
+ /* Even length sampling incompatible with only straight edge sampling for now. */
+ BKE_profilewidget_create_samples_even_spacing(prwdgt, n_samples, new_table);
+ }
+ else {
+ BKE_profilewidget_create_samples(prwdgt, n_samples, prwdgt->flag & PROF_SAMPLE_STRAIGHT_EDGES,
+ new_table);
+ }
if (prwdgt->segments) {
MEM_freeN(prwdgt->segments);
}
prwdgt->segments = new_table;
+
}
/** Sets the default settings and clip range for the profile widget. Does not generate either
@@ -863,81 +863,83 @@ void BKE_profilewidget_initialize(ProfileWidget *prwdgt, short nsegments)
{
prwdgt->totsegments = nsegments;
- /* Calculate the higher resolution tables for display and evaluation. */
+ /* Calculate the higher resolution / segments tables for display and evaluation. */
BKE_profilewidget_changed(prwdgt, false);
}
/** Gives the distance to the next point in the widget's sampled table, in other words the length
* of the ith edge of the table.
* \note Requires profilewidget_initialize or profilewidget_changed call before to fill table. */
-static float profilewidget_distance_to_next_point(const ProfileWidget *prwdgt, int i)
+static float profilewidget_distance_to_next_table_point(const ProfileWidget *prwdgt, int i)
{
- BLI_assert(prwdgt != NULL);
- BLI_assert(i >= 0);
- BLI_assert(i < prwdgt->totpoint);
-
- float x = prwdgt->table[i].x;
- float y = prwdgt->table[i].y;
- float x_next = prwdgt->table[i + 1].x;
- float y_next = prwdgt->table[i + 1].y;
+ BLI_assert(i < PROF_N_TABLE(prwdgt->totpoint));
- return sqrtf(powf(y_next - y, 2) + powf(x_next - x, 2));
+ return len_v2v2(&prwdgt->table[i].x, &prwdgt->table[i + 1].x);
}
/** Calculates the total length of the profile from the curves sampled in the table.
* \note Requires profilewidget_initialize or profilewidget_changed call before to fill table. */
float BKE_profilewidget_total_length(const ProfileWidget *prwdgt)
{
- float loc1[2], loc2[2];
float total_length = 0;
-
- for (int i = 0; i < PROF_N_TABLE(prwdgt->totpoint); i++) {
- loc1[0] = prwdgt->table[i].x;
- loc1[1] = prwdgt->table[i].y;
- loc2[0] = prwdgt->table[i].x;
- loc2[1] = prwdgt->table[i].y;
- total_length += len_v2v2(loc1, loc2);
+ for (int i = 0; i < PROF_N_TABLE(prwdgt->totpoint) - 1; i++) {
+ total_length += len_v2v2(&prwdgt->table[i].x, &prwdgt->table[i + 1].x);
}
return total_length;
}
/** Samples evenly spaced positions along the profile widget's table (generated from path). Fills
* an entire table at once for a speedup if all of the results are going to be used anyway.
- * \note Requires profilewidget_initialize or profilewidget_changed call before to fill table. */
-/* HANS-TODO: Enable this for an "even length sampling" option (and debug it). */
-void BKE_profilewidget_create_samples_even_spacing(const ProfileWidget *prwdgt,
- double *x_table_out,
- double *y_table_out)
+ * \note Requires profilewidget_initialize or profilewidget_changed call before to fill table.
+ * \note Working, but would conflict with "Sample Straight Edges" option, so this is unused for now. */
+void BKE_profilewidget_create_samples_even_spacing(ProfileWidget *prwdgt,
+ int n_segments,
+ ProfilePoint *r_samples)
{
const float total_length = BKE_profilewidget_total_length(prwdgt);
- const float segment_length = total_length / prwdgt->totsegments;
+ const float segment_length = total_length / n_segments;
float length_travelled = 0.0f;
- float distance_to_next_point = profilewidget_distance_to_next_point(prwdgt, 0);
- float distance_to_previous_point = 0.0f;
- float travelled_since_last_point = 0.0f;
- float segment_left = segment_length;
- float f;
- int i_point = 0;
+ float distance_to_next_table_point = profilewidget_distance_to_next_table_point(prwdgt, 0);
+ float distance_to_previous_table_point = 0.0f;
+ float segment_left, factor;
+ int i_table = 0;
+
+ /* Set the location for the first point. */
+ r_samples[0].x = prwdgt->table[0].x;
+ r_samples[0].y = prwdgt->table[0].y;
/* Travel along the path, recording the locations of segments as we pass them. */
- for (int i = 0; i < prwdgt->totsegments; i++) {
- /* Travel over all of the points that could be inside this segment. */
- while (distance_to_next_point > segment_length * (i + 1) - length_travelled) {
- length_travelled += distance_to_next_point;
- segment_left -= distance_to_next_point;
- travelled_since_last_point += distance_to_next_point;
- i_point++;
- distance_to_next_point = profilewidget_distance_to_next_point(prwdgt, i_point);
- distance_to_previous_point = 0.0f;
+ segment_left = segment_length;
+ for (int i = 1; i < n_segments; i++) {
+ /* Travel over all of the points that fit inside this segment. */
+ while (distance_to_next_table_point < segment_left) {
+ length_travelled += distance_to_next_table_point;
+ segment_left -= distance_to_next_table_point;
+ i_table++;
+ distance_to_next_table_point = profilewidget_distance_to_next_table_point(prwdgt, i_table);
+ distance_to_previous_table_point = 0.0f;
}
- /* We're now at the last point that fits inside the current segment. */
- f = segment_left / (distance_to_previous_point + distance_to_next_point);
- x_table_out[i] = (double)interpf(prwdgt->table[i_point].x, prwdgt->table[i_point + 1].x, f);
- y_table_out[i] = (double)interpf(prwdgt->table[i_point].x, prwdgt->table[i_point + 1].x, f);
- distance_to_next_point -= segment_left;
- distance_to_previous_point += segment_left;
+ /* We're at the last table point that fits inside the current segment, use interpolation. */
+ factor = (distance_to_previous_table_point + segment_left) / (distance_to_previous_table_point + distance_to_next_table_point);
+ r_samples[i].x = interpf(prwdgt->table[i_table + 1].x, prwdgt->table[i_table].x, factor);
+ r_samples[i].y = interpf(prwdgt->table[i_table + 1].y, prwdgt->table[i_table].y, factor);
+#ifdef DEBUG_PRWDGT_EVALUATE
+ BLI_assert(factor <= 1.0f && factor >= 0.0f);
+ printf("segment_left: %.3f\n", segment_left);
+ printf("i_table: %d\n", i_table);
+ printf("distance_to_previous_table_point: %.3f\n", distance_to_previous_table_point);
+ printf("distance_to_next_table_point: %.3f\n", distance_to_next_table_point);
+ printf("Interpolating with factor %.3f from (%.3f, %.3f) to (%.3f, %.3f)\n\n",
+ factor,
+ prwdgt->table[i_table].x, prwdgt->table[i_table].y,
+ prwdgt->table[i_table + 1].x, prwdgt->table[i_table + 1].y);
+#endif
+ /* We sampled in between this table point and the next, so the next travel step is smaller. */
+ distance_to_next_table_point -= segment_left;
+ distance_to_previous_table_point += segment_left;
length_travelled += segment_left;
+ segment_left = segment_length;
}
}
@@ -964,7 +966,7 @@ void BKE_profilewidget_evaluate_length_portion(const ProfileWidget *prwdgt,
if (i == PROF_N_TABLE(prwdgt->totpoint) - 2) {
break;
}
- float new_length = profilewidget_distance_to_next_point(prwdgt, i);
+ float new_length = profilewidget_d
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list