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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs