[Bf-blender-cvs] [76051848362] soc-2019-bevel-profiles: Working towards using the profile information in simple bevel cases, and started some faster (O(n) vs O(n^2)) sampling code for the profile paths. Adding lots of questions and TODOs...
Hans Goudey
noreply at git.blender.org
Sat Jun 1 07:39:10 CEST 2019
Commit: 76051848362847ffabb5bddf858ad9c69f5481fc
Author: Hans Goudey
Date: Fri May 31 21:39:21 2019 -0400
Branches: soc-2019-bevel-profiles
https://developer.blender.org/rB76051848362847ffabb5bddf858ad9c69f5481fc
Working towards using the profile information in simple bevel cases, and started some faster (O(n) vs O(n^2)) sampling code for the profile paths. Adding lots of questions and TODOs...
===================================================================
M source/blender/blenkernel/intern/colortools.c
M source/blender/bmesh/tools/bmesh_bevel.c
M source/blender/makesdna/DNA_color_types.h
===================================================================
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 6889612e65d..5585bbdf3a2 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -904,7 +904,8 @@ void curvemapping_changed(CurveMapping *cumap, const bool rem_doubles)
}
}
-// qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints);
+ /* HANS-TODO: Reenable this for other curves! */
+ /* qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints); */
/* remove doubles, threshold set on 1% of default range */
if (rem_doubles && cuma->totpoint > 2) {
@@ -1291,8 +1292,46 @@ void curvemap_path_evaluate(const struct CurveMap *cuma, float length_portion, f
*y_out = lerp(cuma->curve[i].y, cuma->curve[i+1].y, lerp_factor);
}
-static void curvemap_path_make_table(const struct CurveMap *cuma) {
+
+/* HANS-TODO: Fix this, it can't be the right method, because it doesn't generalize well to
+ * small distances between points. There could be a lot of points inside one segment length,
+ * but this code assumes that there's only 1. I need to think harder about what method to use here.
+ * But really it might not be worth pursuing this much because there might be a more general solution
+ * that includes curves and the small speedup it would give isn't a high priority right now */
+static void curvemap_path_make_table(struct CurveMap *cuma) {
/* Fill table with values for the position of the graph at each of the segments */
+ float segment_length = cuma->total_length / cuma->nsegments;
+ float length_travelled = 0.0f;
+ float distance_to_next_point = curvemap_path_linear_distance_to_next_point(cuma, 0);
+ float distance_to_previous_point = 0.0f;
+ float f;
+ int i_point = 0;
+
+ cuma->x_segment_vals = MEM_callocN((size_t)cuma->nsegments * sizeof(float), "segment table x");
+ cuma->y_segment_vals = MEM_callocN((size_t)cuma->nsegments * sizeof(float), "segment table y"); /* HANS-TODO: Free these!! Where?? */
+
+ /* Travel along the path, recording locations of segments as we pass where they should be */
+ for (int i = 0; i < cuma->nsegments; i++) {
+ if (segment_length < distance_to_next_point) {
+ /* There is room for the next segment before the next point */
+ f = (distance_to_previous_point + segment_length) / (distance_to_previous_point + distance_to_next_point);
+ cuma->x_segment_vals[i] = lerp(cuma->curve[i_point].x, cuma->curve[i_point+1].x, f);
+ cuma->y_segment_vals[i] = lerp(cuma->curve[i_point].x, cuma->curve[i_point+1].x, f);
+ distance_to_next_point -= segment_length;
+ distance_to_previous_point += segment_length;
+ }
+ else {
+ /* We have to pass over a CurveMapPoint to get to the next segment */
+ float left_after_pass = segment_length - distance_to_next_point;
+ i_point++;
+ distance_to_previous_point = segment_length - distance_to_next_point;
+ distance_to_next_point = curvemap_path_linear_distance_to_next_point(cuma, i_point);
+ f = left_after_pass / (distance_to_previous_point + distance_to_next_point);
+ cuma->x_segment_vals[i] = lerp(cuma->curve[i_point].x, cuma->curve[i_point+1].x, f);
+ cuma->y_segment_vals[i] = lerp(cuma->curve[i_point].x, cuma->curve[i_point+1].x, f);
+ }
+ length_travelled += segment_length;
+ }
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 150732e088c..cc35bf6e31f 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -56,10 +56,9 @@
#define BEVEL_MAX_AUTO_ADJUST_PCT 300.0f
#define BEVEL_MATCH_SPEC_WEIGHT 0.2
-
+#define DEBUG_CUSTOM_PROFILE_SAMPLE 0
#define DEBUG_CUSTOM_PROFILE 1
-
/* happens far too often, uncomment for development */
// #define BEVEL_ASSERT_PROJECT
@@ -1648,11 +1647,104 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int n,
}
-static void calculate_custom_profile(BevelParams *bp, BoundVert *bndv)
-{
+/* This does the same thing as the regular calculate profile function, but it uses the
+ * custom profile points instead of the normal ones. Eventually, when the custom and normal
+ * profile spacings are merged, this function will be redundant, but for now, I will call this
+ * function in certain cases where I am working on the custom profile
+ * HANS-TODO: Get rid of this function when all custom profile cases are completed */
+static void calculate_profile_custom(BevelParams *bp, BoundVert *bndv) {
+ int i, k, ns;
+ const double *xvals, *yvals;
+ float co[3], co2[3], p[3], m[4][4];
+ float *prof_co, *prof_co_k;
+ float r;
+ bool need_2, map_ok;
+ Profile *pro = &bndv->profile;
-}
+ /* HANS-TODO: If the goal of this function is to translate the 2D coords of the profile spacing
+ * into 3D for the actual placement of the profile verts, I'm not sure that this function will
+ * actually have to be changed, because that process should be the same for different vert locations.
+ * So figure out if that's what this function does. */
+ /* This function should do the exact same thing for the custom profiles, so it shouldn't need to be changed */
+
+ if (bp->seg == 1) {
+ return;
+ }
+
+ need_2 = bp->seg != bp->pro_spacing.seg_2;
+ if (!pro->prof_co) {
+ pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, ((size_t)bp->seg + 1) * 3 * sizeof(float));
+ if (need_2) {
+ pro->prof_co_2 = (float *)BLI_memarena_alloc(
+ bp->mem_arena, ((size_t)bp->pro_spacing.seg_2 + 1) * 3 * sizeof(float));
+ }
+ else {
+ pro->prof_co_2 = pro->prof_co;
+ }
+ }
+ r = pro->super_r;
+ if (r == PRO_LINE_R) {
+ map_ok = false;
+ }
+ else {
+ map_ok = make_unit_square_map(pro->coa, pro->midco, pro->cob, m);
+ }
+ /* The first iteration is the nseg case, the second is the seg_2 case if it's needed */
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ ns = bp->seg;
+ xvals = bp->pro_spacing.xvals_custom;
+ yvals = bp->pro_spacing.yvals_custom;
+ prof_co = pro->prof_co;
+ }
+ else {
+ if (!need_2) {
+ break; /* shares coords with pro->prof_co */
+ }
+ ns = bp->pro_spacing.seg_2;
+ xvals = bp->pro_spacing.xvals_2_custom;
+ yvals = bp->pro_spacing.yvals_2_custom;
+ prof_co = pro->prof_co_2;
+ }
+ /* HANS-TODO: Why this assert? */
+ BLI_assert((r == PRO_LINE_R || (xvals != NULL && yvals != NULL)) && prof_co != NULL);
+
+ /* Iterate over the vertices along the boundary arc */
+ for (k = 0; k <= ns; k++) {
+ if (k == 0) {
+ copy_v3_v3(co, pro->coa);
+ }
+ else if (k == ns) {
+ copy_v3_v3(co, pro->cob);
+ }
+ else {
+ if (map_ok) {
+ p[0] = (float)xvals[k];
+ p[1] = (float)yvals[k];
+ p[2] = 0.0f;
+ mul_v3_m4v3(co, m, p); /* HANS-QUESTION: What's the reason to have this and the final projection? */
+ }
+ else {
+ interp_v3_v3v3(co, pro->coa, pro->cob, (float)k / (float)ns);
+ }
+ }
+ /* project co onto final profile plane */
+ prof_co_k = prof_co + 3 * k; /* 3 times deeper because each coord takes up 3 spaces */
+ if (!is_zero_v3(pro->proj_dir)) {
+ add_v3_v3v3(co2, co, pro->proj_dir);
+ /* pro->plane_co and pro->plane_no are build in "set_profile_params" */
+ if (!isect_line_plane_v3(prof_co_k, co, co2, pro->plane_co, pro->plane_no)) {
+ /* shouldn't happen */
+ copy_v3_v3(prof_co_k, co);
+ }
+ }
+ else {
+ copy_v3_v3(prof_co_k, co);
+ }
+ }
+ }
+}
/* Calculate the actual coordinate values for bndv's profile.
* This is only needed if bp->seg > 1.
@@ -1675,12 +1767,8 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv)
* into 3D for the actual placement of the profile verts, I'm not sure that this function will
* actually have to be changed, because that process should be the same for different vert locations.
* So figure out if that's what this function does. */
- /*
- if (bp->use_custom_profile) {
- calculate_custom_profile(bp, bndv);
- return;
- }
- */
+
+ /* This function should do the exact same thing for the custom profiles, so it shouldn't need to be changed */
if (bp->seg == 1) {
return;
@@ -1688,10 +1776,10 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv)
need_2 = bp->seg != bp->pro_spacing.seg_2;
if (!pro->prof_co) {
- pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, (bp->seg + 1) * 3 * sizeof(float));
+ pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, ((size_t)bp->seg + 1) * 3 * sizeof(float));
if (need_2) {
pro->prof_co_2 = (float *)BLI_memarena_alloc(
- bp->mem_arena, (bp->pro_spacing.seg_2 + 1) * 3 * sizeof(float));
+ bp->mem_arena, ((size_t)bp->pro_spacing.seg_2 + 1) * 3 * sizeof(float));
}
else {
pro->prof_co_2 = pro->prof_co;
@@ -1704,6 +1792,7 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv)
else {
map_ok = make_unit_square_map(pro->coa, pro->midco, pro->cob, m);
}
+ /* The first iteration is the nseg case, the second is the seg_2 case if it's needed */
for (i = 0; i < 2; i++) {
if (i == 0) {
ns = bp->seg;
@@ -1720,7 +1809,10 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv)
yvals = bp->pro_spacing.yvals_2;
prof_co = pro->prof_co_2;
}
+ /* HANS-TODO: Why this assert? */
BLI_assert((r == PRO_LINE_R || (xvals != NULL && yvals != NULL)) && prof_co != NULL);
+
+ /* Iterate over the vertices along the boundary arc */
for (k = 0; k <= ns; k++) {
if (k == 0) {
copy_v3_v3(co, pro->coa);
@@ -1730,19 +1822,20 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv)
}
else {
if (map_ok) {
- p[0] = xvals[k];
- p[1] = yvals[k];
+ p[0] = (float)xvals[k];
+ p[1] = (float)yvals[k];
p[2] = 0.0f;
- mul_v3_m4v3(co, m, p);
+ mul_v3_m4v3(co, m, p); /* HANS-QUESTION: What's the
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list