Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Kim <pk15950@gmail.com>2022-09-08 07:00:12 +0300
committerPeter Kim <pk15950@gmail.com>2022-09-08 07:00:12 +0300
commit00dcfdf916c69672210b006e62d966f1bc2fbeb7 (patch)
tree0cbb1b91fe26c750197126085b74224a795a103c /source/blender/bmesh/tools/bmesh_bevel.c
parenta39532670f6b668da7be5810fb1f844b82feeba3 (diff)
parentd5934974219135102f364f57c45a8b1465e2b8d9 (diff)
Merge branch 'master' into xr-devxr-dev
Diffstat (limited to 'source/blender/bmesh/tools/bmesh_bevel.c')
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c144
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];