wip - alternate bevel curve calculation (still disabled)

now USE_ALTERNATE_ADJ works, giving more stable corners that don't flicker and glitch out as the offset changes.

The shape is not a circle though and doesnt look quite as nice as the existing method.
This commit is contained in:
Campbell Barton
2012-11-16 08:12:06 +00:00
parent 328dd3f033
commit f5b356bf18

View File

@@ -437,7 +437,6 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
madd_v3_v3fl(slideco, dir, -d);
}
#ifndef USE_ALTERNATE_ADJ
/* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco */
static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3], float projco[3])
{
@@ -448,7 +447,6 @@ static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3],
copy_v3_v3(projco, e->v1->co);
}
}
#endif
/* return 1 if a and b are in CCW order on the normal side of f,
* and -1 if they are reversed, and 0 if there is no shared face f */
@@ -515,13 +513,26 @@ static void vmesh_cent(VMesh *vm, float r_cent[3])
*
*/
static void get_point_on_round_edge(EdgeHalf *e, int ring, int k,
static void get_point_uv(float uv[2],
/* all these args are int's originally
* but pass as floats to the function */
const float seg, const float ring, const float k)
{
uv[0] = (ring / seg) * 2.0f;
uv[1] = (k / seg) * 2.0f;
}
/* TODO: make this a lot smarter!,
* this is the main reason USE_ALTERNATE_ADJ isn't so good right now :S */
static float get_point_uv_factor(const float uv[2])
{
return sinf(1.0f - max_ff(uv[0], uv[1]) / 2.0f);
}
static void get_point_on_round_edge(const float uv[2],
float quad[4][3],
float r_co[3])
{
const float n = e->seg;
const float uv[2] = {(ring / n) * 2.0f, (k / n) * 2.0f};
interp_bilinear_quad_v3(quad, uv[0], uv[1], r_co);
}
@@ -763,9 +774,15 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
#ifdef USE_ALTERNATE_ADJ
/* ordered as follows (orig, prev, center, next)*/
float quad[4][3];
float quad_plane[4][3];
float quad_orig[4][3];
#endif
#ifdef USE_ALTERNATE_ADJ
/* the rest are initialized inline, this remains the same for all */
vmesh_cent(vm, quad[2]);
vmesh_cent(vm, quad_plane[2]);
copy_v3_v3(quad_orig[2], bv->v->co);
#endif
n = vm->count;
@@ -805,15 +822,33 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
nv->v = nvnext->v;
#ifdef USE_ALTERNATE_ADJ
copy_v3_v3(quad[0], v->nv.co);
mid_v3_v3v3(quad[1], v->nv.co, v->prev->nv.co);
/* plane */
copy_v3_v3(quad_plane[0], v->nv.co);
mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
/* quad[2] is set */
mid_v3_v3v3(quad[3], v->nv.co, v->next->nv.co);
mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
/* orig */
copy_v3_v3(quad_orig[0], v->nv.co); /* only shared location between 2 quads */
project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig[1]);
project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig[3]);
//bl_debug_draw_quad_add(UNPACK4(quad_plane));
//bl_debug_draw_quad_add(UNPACK4(quad_orig));
#endif
#ifdef USE_ALTERNATE_ADJ
for (k = 1; k < ns; k++) {
get_point_on_round_edge(v->ebev, ring, k, quad, co);
float uv[2];
float fac;
float co_plane[3];
float co_orig[3];
get_point_uv(uv, v->ebev->seg, ring, k);
get_point_on_round_edge(uv, quad_plane, co_plane);
get_point_on_round_edge(uv, quad_orig, co_orig);
fac = get_point_uv_factor(uv);
interp_v3_v3v3(co, co_plane, co_orig, fac);
copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
}
#else
@@ -1190,14 +1225,20 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
#ifdef USE_ALTERNATE_ADJ
/* ordered as follows (orig, prev, center, next)*/
float quad[4][3];
float quad_plane[4][3];
float quad_orig_a[4][3];
float quad_orig_b[4][3];
const int is_odd = (vm->seg % 2);
#else
float midco[3];
#endif
#ifdef USE_ALTERNATE_ADJ
/* the rest are initialized inline, this remains the same for all */
vmesh_cent(vm, quad[2]);
/* NOTE; in this usage we only interpolate on the 'V' so cent and next points are unused (2,3)*/
vmesh_cent(vm, quad_plane[2]);
copy_v3_v3(quad_orig_a[2], bv->v->co);
copy_v3_v3(quad_orig_b[2], bv->v->co);
#endif
n = vm->count;
@@ -1228,25 +1269,62 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
/* copy other ends to (i, 0, ns) for all i, and fill in profiles for beveled edges */
v = vm->boundstart;
do {
#ifdef USE_ALTERNATE_ADJ
copy_v3_v3(quad[0], v->nv.co);
mid_v3_v3v3(quad[1], v->nv.co, v->prev->nv.co);
/* quad[2] is set */
mid_v3_v3v3(quad[3], v->nv.co, v->next->nv.co);
#endif
i = v->index;
copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
if (v->ebev) {
#ifdef USE_ALTERNATE_ADJ
copy_v3_v3(quad_plane[0], v->nv.co);
mid_v3_v3v3(quad_plane[1], v->nv.co, v->prev->nv.co);
/* quad[2] is set */
mid_v3_v3v3(quad_plane[3], v->nv.co, v->next->nv.co);
/* orig 'A' */
copy_v3_v3(quad_orig_a[0], v->nv.co); /* only shared location between 2 quads */
project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_a[1]);
project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_a[3]);
/* orig 'B' */
copy_v3_v3(quad_orig_b[3], v->next->nv.co); /* only shared location between 2 quads */
project_to_edge(v->ebev->prev->e, v->nv.co, v->prev->nv.co, quad_orig_b[1]);
project_to_edge(v->ebev->e, v->nv.co, v->next->nv.co, quad_orig_b[0]);
//bl_debug_draw_quad_add(UNPACK4(quad_plane));
//bl_debug_draw_quad_add(UNPACK4(quad_orig_a));
//bl_debug_draw_quad_add(UNPACK4(quad_orig_b));
#endif /* USE_ALTERNATE_ADJ */
#ifdef USE_ALTERNATE_ADJ
for (k = 1; k < ns; k++) {
get_point_on_round_edge(v->ebev, 0, k, quad, co);
float uv[2];
float fac;
float co_plane[3];
float co_orig[3];
/* quad_plane */
get_point_uv(uv, v->ebev->seg, 0, k);
get_point_on_round_edge(uv, quad_plane, co_plane);
/* quad_orig */
/* each half has different UV's */
if (k <= ns2) {
get_point_uv(uv, v->ebev->seg, 0, k);
get_point_on_round_edge(uv, quad_orig_a, co_orig);
}
else {
get_point_uv(uv, v->ebev->seg, 0, (k - ns2) - (is_odd ? 0.5f : 0.0f));
get_point_on_round_edge(uv, quad_orig_b, co_orig);
uv[1] = 1.0f - uv[1]; /* so we can get the factor */
}
fac = get_point_uv_factor(uv);
/* done. interp */
interp_v3_v3v3(co, co_plane, co_orig, fac);
copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
if (!weld)
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
}
#else
#else /* USE_ALTERNATE_ADJ */
va = mesh_vert(vm, i, 0, 0)->co;
vb = mesh_vert(vm, i, 0, ns)->co;
project_to_edge(v->ebev->e, va, vb, midco);
@@ -1256,7 +1334,7 @@ static void build_vmesh(MemArena *mem_arena, BMesh *bm, BevVert *bv)
if (!weld)
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
}
#endif
#endif /* !USE_ALTERNATE_ADJ */
}
} while ((v = v->next) != vm->boundstart);