diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2022-08-06 20:16:34 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2022-08-06 20:16:34 +0300 |
commit | fecef2ae7415cd7d7cf7907b2e704ef264fbd242 (patch) | |
tree | b56777d5b5eb89e4d1c90ea3d9ec17a64c436b27 /source/blender/bmesh | |
parent | 8f915f0efba3da652ad06fa9fcfba7d6ca26e719 (diff) | |
parent | d58476049e2ae2e407d66cbb4d5eac65b594509a (diff) |
Merge branch 'blender-v3.3-release'
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.c | 144 |
1 files changed, 32 insertions, 112 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index fa852cdd6da..aa2c93f7c5a 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -437,16 +437,6 @@ static bool nearly_parallel_normalized(const float d1[3], const float d2[3]) return compare_ff(fabsf(direction_dot), 1.0f, BEVEL_EPSILON_ANG_DOT); } -/** - * calculate the determinant of a matrix formed by three vectors - * \return dot(a, cross(b, c)) = determinant(a, b, c) - */ -static float determinant_v3v3v3(const float a[3], const float b[3], const float c[3]) -{ - return a[0] * b[1] * c[2] + a[1] * b[2] * c[0] + a[2] * b[0] * c[1] - a[0] * b[2] * c[1] - - a[1] * b[0] * c[2] - a[2] * b[1] * c[0]; -} - /* Make a new BoundVert of the given kind, inserting it at the end of the circular linked * list with entry point bv->boundstart, and return it. */ static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3]) @@ -4134,114 +4124,44 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in) VMesh *vm_out = new_adj_vmesh(bp->mem_arena, n_boundary, ns_out, vm_in->boundstart); /* First we adjust the boundary vertices of the input mesh, storing in output mesh. */ - BoundVert *bndv = vm_in->boundstart; for (int i = 0; i < n_boundary; i++) { - float co1[3], co2[3], acc[3]; - EdgeHalf *e = bndv->elast; - /* Generate tangents. This is hacked together and would ideally be done elsewhere and then only - * used here. */ - float tangent[3], tangent2[3], normal[3]; - bool convex = true; - bool orthogonal = false; - float stretch = 0.0f; - if (e) { - /* Projection direction is direction of the edge. */ - sub_v3_v3v3(tangent, e->e->v1->co, e->e->v2->co); - if (e->is_rev) { - negate_v3(tangent); - } - normalize_v3(tangent); - if (bndv->is_arc_start || bndv->is_patch_start) { - BMFace *face = e->fnext; - if (face) { - copy_v3_v3(normal, face->no); - } - else { - zero_v3(normal); - } - madd_v3_v3v3fl(co2, bndv->profile.middle, normal, 0.1f); - } - if (bndv->is_arc_start || bp->affect_type == BEVEL_AFFECT_VERTICES) { - EdgeHalf *e1 = bndv->next->elast; - BLI_assert(e1); - sub_v3_v3v3(tangent2, e1->e->v1->co, e1->e->v2->co); - if (e1->is_rev) { - negate_v3(tangent2); - } - normalize_v3(tangent2); - - convex = determinant_v3v3v3(tangent2, tangent, normal) < 0; - - add_v3_v3(tangent2, tangent); - normalize_v3(tangent2); - copy_v3_v3(tangent, tangent2); - } - /* Calculate a factor which determines how much the interpolated mesh is - * going to be stretched out into the direction of the tangent. - * It is currently using the difference along the tangent of the - * central point on the profile and the current center vertex position. */ - get_profile_point(bp, &bndv->profile, ns_in2, ns_in, co); - stretch = dot_v3v3(tangent, mesh_vert(vm_in, i, ns_in2, ns_in2)->co) - dot_v3v3(tangent, co); - stretch = fabsf(stretch); - /* Scale the tangent by stretch. The divide by ns_in2 comes from the Levin Paper. */ - mul_v3_fl(tangent, stretch / ns_in2); - orthogonal = bndv->is_patch_start; - } - else if (bndv->prev->is_patch_start) { - /* If this is the second edge of a patch and therefore #e is NULL, - * then e->fprev has to be used/not NULL. */ - BLI_assert(bndv->prev->elast); - BMFace *face = bndv->prev->elast->fnext; - if (face) { - copy_v3_v3(normal, face->no); - } - else { - zero_v3(normal); - } - orthogonal = true; - } - else { - /** Should only come here from make_cube_corner_adj_vmesh. */ - sub_v3_v3v3(co1, mesh_vert(vm_in, i, 0, 0)->co, mesh_vert(vm_in, i, 0, 1)->co); - sub_v3_v3v3(co2, mesh_vert(vm_in, i, 0, 1)->co, mesh_vert(vm_in, i, 0, 2)->co); - cross_v3_v3v3(tangent, co1, co2); - /** The following constant is chosen to best match the old results. */ - normalize_v3_length(tangent, 1.5f / ns_out); - } - /** Copy corner vertex. */ copy_v3_v3(mesh_vert(vm_out, i, 0, 0)->co, mesh_vert(vm_in, i, 0, 0)->co); - /** Copy the rest of the boundary vertices. */ for (int k = 1; k < ns_in; k++) { copy_v3_v3(co, mesh_vert(vm_in, i, 0, k)->co); - copy_v3_v3(co1, mesh_vert(vm_in, i, 0, k - 1)->co); - copy_v3_v3(co2, mesh_vert(vm_in, i, 0, k + 1)->co); - - add_v3_v3v3(acc, co1, co2); - if (bndv->is_arc_start) { - sub_v3_v3(co1, co); - sub_v3_v3(co2, co); - normalize_v3(co1); - normalize_v3(co2); - add_v3_v3v3(tangent, co1, co2); - /* This is an empirical formula to make the result look good. */ - normalize_v3(tangent); - float dot = convex ? fminf(0, dot_v3v3(tangent2, tangent)) : 1.0f; - mul_v3_fl(tangent, stretch / ns_in * dot); - } - else if (orthogonal) { - sub_v3_v3(co1, co); - cross_v3_v3v3(tangent, normal, co1); - /* This is an empirical formula to make the result look good. */ - normalize_v3_length(tangent, -bp->offset * 0.7071f / ns_in); - } - mul_v3_fl(co, 2.0f); - madd_v3_v3fl(co, acc, -0.25f); - madd_v3_v3fl(co, mesh_vert(vm_in, i, 1, k)->co, -0.5f); - add_v3_v3(co, tangent); + /* Smooth boundary rule. Custom profiles shouldn't be smoothed. */ + if (bp->profile_type != BEVEL_PROFILE_CUSTOM) { + float co1[3], co2[3], acc[3]; + copy_v3_v3(co1, mesh_vert(vm_in, i, 0, k - 1)->co); + copy_v3_v3(co2, mesh_vert(vm_in, i, 0, k + 1)->co); + + add_v3_v3v3(acc, co1, co2); + madd_v3_v3fl(acc, co, -2.0f); + madd_v3_v3fl(co, acc, -1.0f / 6.0f); + } copy_v3_v3(mesh_vert_canon(vm_out, i, 0, 2 * k)->co, co); } + } + /* Now adjust odd boundary vertices in output mesh, based on even ones. */ + BoundVert *bndv = vm_out->boundstart; + for (int i = 0; i < n_boundary; i++) { + for (int k = 1; k < ns_out; k += 2) { + get_profile_point(bp, &bndv->profile, k, ns_out, co); + + /* Smooth if using a non-custom profile. */ + if (bp->profile_type != BEVEL_PROFILE_CUSTOM) { + float co1[3], co2[3], acc[3]; + copy_v3_v3(co1, mesh_vert_canon(vm_out, i, 0, k - 1)->co); + copy_v3_v3(co2, mesh_vert_canon(vm_out, i, 0, k + 1)->co); + + add_v3_v3v3(acc, co1, co2); + madd_v3_v3fl(acc, co, -2.0f); + madd_v3_v3fl(co, acc, -1.0f / 6.0f); + } + + copy_v3_v3(mesh_vert_canon(vm_out, i, 0, k)->co, co); + } bndv = bndv->next; } vmesh_copy_equiv_verts(vm_out); @@ -4249,7 +4169,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in) /* Copy adjusted verts back into vm_in. */ for (int i = 0; i < n_boundary; i++) { for (int k = 0; k < ns_in; k++) { - copy_v3_v3(mesh_vert_canon(vm_in, i, 0, k)->co, mesh_vert_canon(vm_out, i, 0, 2 * k)->co); + copy_v3_v3(mesh_vert(vm_in, i, 0, k)->co, mesh_vert(vm_out, i, 0, 2 * k)->co); } } @@ -4334,7 +4254,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm_in) vmesh_copy_equiv_verts(vm_out); /* The center vertex is special. */ - gamma = sabin_gamma(n_boundary) * 0.5f; + gamma = sabin_gamma(n_boundary); beta = -gamma; /* Accumulate edge verts in co1, face verts in co2. */ float co1[3], co2[3]; |