Bevel - better corner shapes for inner arc miters.
authorHoward Trickey <howard.trickey@gmail.com>
Tue, 29 Jan 2019 12:21:59 +0000 (07:21 -0500)
committerHoward Trickey <howard.trickey@gmail.com>
Tue, 29 Jan 2019 12:21:59 +0000 (07:21 -0500)
The subdivision method for getting corner shapes has a fullness
parameter which had been set by eye before. This change uses fullness
as found by offline search process to best match the superellipsoid
octant in the cube corner case (except cube corner case is still handled
by other code). This somewhat improves the look of cube corners with
inner arc miters, however.

release/datafiles/locale
release/scripts/addons
release/scripts/addons_contrib
source/blender/bmesh/tools/bmesh_bevel.c
source/tools

index 8eafc437295b0edc990db231fe957e2ad42af70d..4be9fbe61cb1e23baf25c9c379ecd13e22ca1898 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8eafc437295b0edc990db231fe957e2ad42af70d
+Subproject commit 4be9fbe61cb1e23baf25c9c379ecd13e22ca1898
index ba97e19e5b3df449784a4cc4ed89ce7b511ec3e4..8b93448f56ecdf9c91ad1b6297580eedf1f6e18f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit ba97e19e5b3df449784a4cc4ed89ce7b511ec3e4
+Subproject commit 8b93448f56ecdf9c91ad1b6297580eedf1f6e18f
index 272b1a4ef07717beb3d0bfcb7380c2164fd008a3..059f8cc709c5d377241958ef3bb2673328f9849e 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 272b1a4ef07717beb3d0bfcb7380c2164fd008a3
+Subproject commit 059f8cc709c5d377241958ef3bb2673328f9849e
index 5d4082aded4a54dd40b8c44a7b9060a5cdd434f9..159520d6d67c480650567b22c3e5ffa947f9fe08 100644 (file)
@@ -209,6 +209,7 @@ typedef struct BevelParams {
        float offset;           /* blender units to offset each side of a beveled edge */
        int offset_type;        /* how offset is measured; enum defined in bmesh_operators.h */
        int seg;                /* number of segments in beveled edge profile */
+       float profile;          /* user profile setting */
        float pro_super_r;      /* superellipse parameter for edge profile */
        bool vertex_only;       /* bevel vertices only */
        bool use_weights;       /* bevel amount affected by weights on edges or verts */
@@ -3592,7 +3593,23 @@ static VMesh *adj_vmesh(BevelParams *bp, BevVert *bv)
        float co[3], coa[3], cob[3], dir[3];
        BoundVert *bndv;
        MemArena *mem_arena = bp->mem_arena;
-       float r, fac, fullness;
+       float r, p, fullness;
+       /* best fullness for circles, segs = 2,4,6,8,10 */
+#define CIRCLE_FULLNESS_SEGS 11
+       static const float circle_fullness[CIRCLE_FULLNESS_SEGS] = {
+               0.0f,  /* nsegs ==1 */
+               0.559f,  /* 2 */
+               0.642f,  /* 3 */
+               0.551f,  /* 4 */
+               0.646f,  /* 5 */
+               0.624f,  /* 6 */
+               0.646f,  /* 7 */
+               0.619f,  /* 8 */
+               0.647f,  /* 9 */
+               0.639f,  /* 10 */
+               0.647f,  /* 11 */
+               };
+
        n = bv->vmesh->count;
 
        /* Same bevel as that of 3 edges of vert in a cube */
@@ -3624,20 +3641,25 @@ static VMesh *adj_vmesh(BevelParams *bp, BevVert *bv)
        mul_v3_fl(co, 1.0f / (float)n);
        sub_v3_v3v3(cob, co, coa);
        add_v3_v3(cob, co);
+
+       /* An offline optimization process found fullness that let to closest fit to sphere as
+        * a function of r and ns (for case of cube corner) */
        r = bp->pro_super_r;
-       if (r == 1.0f)
+       p = bp->profile;
+       if (r == PRO_LINE_R) {
                fullness = 0.0f;
-       else if (r > 1.0f) {
-               if (bp->vertex_only)
-                       fac = 0.25f;
-               else if (r == PRO_SQUARE_R)
-                       fac = -2.0;
-               else
-                       fac = 0.5f;
-               fullness = 1.0f - fac / r;
+       }
+       else if (r == PRO_CIRCLE_R && ns > 0 && ns <= CIRCLE_FULLNESS_SEGS) {
+               fullness = circle_fullness[ns - 1];
        }
        else {
-               fullness = r - 1.0f;
+               /* linear regression fit found best linear function, separately for even/odd segs */
+               if (ns % 2 == 0) {
+                       fullness = 2.4506f * p - 0.00000300f * ns - 0.6266f;
+               }
+               else {
+                       fullness = 2.3635f * p + 0.000152f * ns - 0.6060f;
+               }
        }
        sub_v3_v3v3(dir, coa, co);
        if (len_squared_v3(dir) > BEVEL_EPSILON_SQ)
@@ -6030,6 +6052,7 @@ void BM_mesh_bevel(
        bp.offset = offset;
        bp.offset_type = offset_type;
        bp.seg    = segments;
+       bp.profile = profile;
        bp.pro_super_r = -log(2.0) / log(sqrt(profile));  /* convert to superellipse exponent */
        bp.vertex_only = vertex_only;
        bp.use_weights = use_weights;
index aef8f32086b9393d286c49cbe5a51ae465fe0589..83428cbf0a8d7e0bdd7a91c00124381c1db42e70 160000 (submodule)
@@ -1 +1 @@
-Subproject commit aef8f32086b9393d286c49cbe5a51ae465fe0589
+Subproject commit 83428cbf0a8d7e0bdd7a91c00124381c1db42e70