forked from bartvdbraak/blender
Bevel code cleanup: get rid of old 'ADJ' code.
The new subdiv 'adj' pattern is working well, so removing the old code and taking opportunity to remove 'subdiv' from a number of names.
This commit is contained in:
parent
be6643b5ec
commit
37f1b717eb
@ -49,9 +49,6 @@
|
|||||||
|
|
||||||
#include "./intern/bmesh_private.h"
|
#include "./intern/bmesh_private.h"
|
||||||
|
|
||||||
/* use new way of doing ADJ pattern */
|
|
||||||
#define USE_ADJ_SUBDIV
|
|
||||||
|
|
||||||
#define BEVEL_EPSILON_D 1e-6
|
#define BEVEL_EPSILON_D 1e-6
|
||||||
#define BEVEL_EPSILON 1e-6f
|
#define BEVEL_EPSILON 1e-6f
|
||||||
#define BEVEL_EPSILON_SQ 1e-12f
|
#define BEVEL_EPSILON_SQ 1e-12f
|
||||||
@ -151,7 +148,6 @@ typedef struct VMesh {
|
|||||||
M_NONE, /* no polygon mesh needed */
|
M_NONE, /* no polygon mesh needed */
|
||||||
M_POLY, /* a simple polygon */
|
M_POLY, /* a simple polygon */
|
||||||
M_ADJ, /* "adjacent edges" mesh pattern */
|
M_ADJ, /* "adjacent edges" mesh pattern */
|
||||||
M_ADJ_SUBDIV, /* like M_ADJ, but using subdivision */
|
|
||||||
M_TRI_FAN, /* a simple polygon - fan filled */
|
M_TRI_FAN, /* a simple polygon - fan filled */
|
||||||
M_QUAD_STRIP, /* a simple polygon - cut into parallel strips */
|
M_QUAD_STRIP, /* a simple polygon - cut into parallel strips */
|
||||||
} mesh_kind;
|
} mesh_kind;
|
||||||
@ -1081,37 +1077,6 @@ static void make_unit_cube_map(const float va[3], const float vb[3], const float
|
|||||||
r_mat[3][3] = 1.0f;
|
r_mat[3][3] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_ADJ_SUBDIV
|
|
||||||
/*
|
|
||||||
* Find the point (/n) of the way around the round profile for e,
|
|
||||||
* where start point is va, midarc point is vmid, and end point is vb.
|
|
||||||
* Return the answer in r_co.
|
|
||||||
* If va -- vmid -- vb is approximately a straight line, just
|
|
||||||
* interpolate along the line.
|
|
||||||
*/
|
|
||||||
static void get_point_on_round_edge(EdgeHalf *e, int k,
|
|
||||||
const float va[3], const float vmid[3], const float vb[3],
|
|
||||||
float r_co[3])
|
|
||||||
{
|
|
||||||
float p[3], angle;
|
|
||||||
float m[4][4];
|
|
||||||
int n = e->seg;
|
|
||||||
|
|
||||||
if (make_unit_square_map(va, vmid, vb, m)) {
|
|
||||||
/* Find point k/(e->seg) along quarter circle from (0,1,0) to (1,0,0) */
|
|
||||||
angle = (float)M_PI * (float)k / (2.0f * (float)n); /* angle from y axis */
|
|
||||||
p[0] = sinf(angle);
|
|
||||||
p[1] = cosf(angle);
|
|
||||||
p[2] = 0.0f;
|
|
||||||
mul_v3_m4v3(r_co, m, p);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* degenerate case: profile is a line */
|
|
||||||
interp_v3_v3v3(r_co, va, vb, (float)k / (float)n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get the coordinate on the superellipse (exponent r),
|
/* Get the coordinate on the superellipse (exponent r),
|
||||||
* at parameter value u. u goes from u to 2 as the
|
* at parameter value u. u goes from u to 2 as the
|
||||||
* superellipse moves on the quadrant (0,1) to (1,0). */
|
* superellipse moves on the quadrant (0,1) to (1,0). */
|
||||||
@ -1202,7 +1167,7 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int n,
|
|||||||
* Allocate the space for them if that hasn't been done already.
|
* Allocate the space for them if that hasn't been done already.
|
||||||
* If bp->seg is not a power of 2, also need to calculate
|
* If bp->seg is not a power of 2, also need to calculate
|
||||||
* the coordinate values for the power of 2 >= bp->seg,
|
* the coordinate values for the power of 2 >= bp->seg,
|
||||||
* because the ADJ_SUBDIV pattern needs power-of-2 boundaries
|
* because the ADJ pattern needs power-of-2 boundaries
|
||||||
* during construction. */
|
* during construction. */
|
||||||
static void calculate_profile(BevelParams *bp, BoundVert *bndv)
|
static void calculate_profile(BevelParams *bp, BoundVert *bndv)
|
||||||
{
|
{
|
||||||
@ -1275,45 +1240,6 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_ADJ_SUBDIV
|
|
||||||
/* Calculate a snapped point to the transformed profile of edge e, extended as
|
|
||||||
* in a cylinder-like surface in the direction of e.
|
|
||||||
* co is the point to snap and is modified in place.
|
|
||||||
* va and vb are the limits of the profile (with peak on e). */
|
|
||||||
static void snap_to_edge_profile(EdgeHalf *e, const float va[3], const float vb[3],
|
|
||||||
float co[3])
|
|
||||||
{
|
|
||||||
float m[4][4], minv[4][4];
|
|
||||||
float edir[3], va0[3], vb0[3], vmid0[3], p[3], snap[3], plane[4];
|
|
||||||
|
|
||||||
sub_v3_v3v3(edir, e->e->v1->co, e->e->v2->co);
|
|
||||||
|
|
||||||
/* project va and vb onto plane P, with normal edir and containing co */
|
|
||||||
plane_from_point_normal_v3(plane, co, edir);
|
|
||||||
closest_to_plane_v3(va0, plane, va);
|
|
||||||
closest_to_plane_v3(vb0, plane, vb);
|
|
||||||
project_to_edge(e->e, va0, vb0, vmid0);
|
|
||||||
if (make_unit_square_map(va0, vmid0, vb0, m)) {
|
|
||||||
/* Transform co and project it onto the unit circle.
|
|
||||||
* Projecting is in fact just normalizing the transformed co */
|
|
||||||
if (!invert_m4_m4(minv, m)) {
|
|
||||||
/* shouldn't happen, by angle test and construction of vd */
|
|
||||||
BLI_assert(!"failed inverse during profile snap");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mul_v3_m4v3(p, minv, co);
|
|
||||||
normalize_v3(p);
|
|
||||||
mul_v3_m4v3(snap, m, p);
|
|
||||||
copy_v3_v3(co, snap);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* planar case: just snap to line va--vb */
|
|
||||||
closest_to_line_segment_v3(p, co, va, vb);
|
|
||||||
copy_v3_v3(co, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Snap a direction co to a superellipsoid with parameter super_r */
|
/* Snap a direction co to a superellipsoid with parameter super_r */
|
||||||
static void snap_to_superellipsoid(float co[3], const float super_r)
|
static void snap_to_superellipsoid(float co[3], const float super_r)
|
||||||
{
|
{
|
||||||
@ -1613,7 +1539,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
|
|||||||
if (vm->count == 2)
|
if (vm->count == 2)
|
||||||
vm->mesh_kind = M_NONE;
|
vm->mesh_kind = M_NONE;
|
||||||
else if (bp->seg > 1)
|
else if (bp->seg > 1)
|
||||||
vm->mesh_kind = M_ADJ_SUBDIV;
|
vm->mesh_kind = M_ADJ;
|
||||||
else
|
else
|
||||||
vm->mesh_kind = M_POLY;
|
vm->mesh_kind = M_POLY;
|
||||||
}
|
}
|
||||||
@ -1632,11 +1558,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef USE_ADJ_SUBDIV
|
|
||||||
vm->mesh_kind = M_ADJ_SUBDIV;
|
|
||||||
#else
|
|
||||||
vm->mesh_kind = M_ADJ;
|
vm->mesh_kind = M_ADJ;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1747,362 +1669,7 @@ static EdgeHalf *pipe_test(BevVert *bv)
|
|||||||
return epipe;
|
return epipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef USE_ADJ_SUBDIV
|
static VMesh *new_adj_vmesh(MemArena *mem_arena, int count, int seg, BoundVert *bounds)
|
||||||
/*
|
|
||||||
* Given that the boundary is built and the boundary BMVerts have been made,
|
|
||||||
* calculate the positions of the interior mesh points for the M_ADJ pattern,
|
|
||||||
* then make the BMVerts and the new faces. */
|
|
||||||
static void bevel_build_rings(BMesh *bm, BevVert *bv)
|
|
||||||
{
|
|
||||||
int k, ring, i, n, ns, ns2, nn, odd;
|
|
||||||
VMesh *vm = bv->vmesh;
|
|
||||||
BoundVert *v, *vprev, *vnext;
|
|
||||||
NewVert *nv, *nvprev, *nvnext;
|
|
||||||
EdgeHalf *epipe;
|
|
||||||
BMVert *bmv, *bmv1, *bmv2, *bmv3, *bmv4;
|
|
||||||
BMFace *f, *f2, *f23;
|
|
||||||
float co[3], coa[3], cob[3], midco[3];
|
|
||||||
float va_pipe[3], vb_pipe[3];
|
|
||||||
|
|
||||||
n = vm->count;
|
|
||||||
ns = vm->seg;
|
|
||||||
ns2 = ns / 2;
|
|
||||||
odd = (ns % 2) != 0;
|
|
||||||
BLI_assert(n > 2 && ns > 1);
|
|
||||||
|
|
||||||
epipe = pipe_test(bv);
|
|
||||||
|
|
||||||
/* Make initial rings, going between points on neighbors.
|
|
||||||
* After this loop, will have coords for all (i, r, k) where
|
|
||||||
* BoundVert for i has a bevel, 0 <= r <= ns2, 0 <= k <= ns */
|
|
||||||
for (ring = 1; ring <= ns2; ring++) {
|
|
||||||
v = vm->boundstart;
|
|
||||||
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
if (v->ebev) {
|
|
||||||
/* get points coords of points a and b, on outer rings
|
|
||||||
* of prev and next edges, k away from this edge */
|
|
||||||
vprev = v->prev;
|
|
||||||
vnext = v->next;
|
|
||||||
|
|
||||||
if (vprev->ebev)
|
|
||||||
nvprev = mesh_vert(vm, vprev->index, 0, ns - ring);
|
|
||||||
else
|
|
||||||
nvprev = mesh_vert(vm, vprev->index, 0, ns);
|
|
||||||
copy_v3_v3(coa, nvprev->co);
|
|
||||||
nv = mesh_vert(vm, i, ring, 0);
|
|
||||||
copy_v3_v3(nv->co, coa);
|
|
||||||
nv->v = nvprev->v;
|
|
||||||
|
|
||||||
if (vnext->ebev)
|
|
||||||
nvnext = mesh_vert(vm, vnext->index, 0, ring);
|
|
||||||
else
|
|
||||||
nvnext = mesh_vert(vm, vnext->index, 0, 0);
|
|
||||||
copy_v3_v3(cob, nvnext->co);
|
|
||||||
nv = mesh_vert(vm, i, ring, ns);
|
|
||||||
copy_v3_v3(nv->co, cob);
|
|
||||||
nv->v = nvnext->v;
|
|
||||||
|
|
||||||
/* TODO: better calculation of new midarc point? */
|
|
||||||
project_to_edge(v->ebev->e, coa, cob, midco);
|
|
||||||
|
|
||||||
for (k = 1; k < ns; k++) {
|
|
||||||
get_point_on_round_edge(v->ebev, k, coa, midco, cob, co);
|
|
||||||
copy_v3_v3(mesh_vert(vm, i, ring, k)->co, co);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v->ebev == epipe) {
|
|
||||||
/* save profile extremes for later snapping */
|
|
||||||
copy_v3_v3(va_pipe, mesh_vert(vm, i, 0, 0)->co);
|
|
||||||
copy_v3_v3(vb_pipe, mesh_vert(vm, i, 0, ns)->co);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now make sure cross points of rings share coordinates and vertices.
|
|
||||||
* After this loop, will have BMVerts for all (i, r, k) where
|
|
||||||
* i is for a BoundVert that is beveled and has either a predecessor or
|
|
||||||
* successor BoundVert beveled too, and
|
|
||||||
* for odd ns: 0 <= r <= ns2, 0 <= k <= ns
|
|
||||||
* for even ns: 0 <= r < ns2, 0 <= k <= ns except k=ns2 */
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
if (v->ebev) {
|
|
||||||
vprev = v->prev;
|
|
||||||
vnext = v->next;
|
|
||||||
if (vprev->ebev) {
|
|
||||||
for (ring = 1; ring <= ns2; ring++) {
|
|
||||||
for (k = 1; k <= ns2; k++) {
|
|
||||||
if (!odd && (k == ns2 || ring == ns2))
|
|
||||||
continue; /* center line is special case: do after the rest are done */
|
|
||||||
nv = mesh_vert(vm, i, ring, k);
|
|
||||||
nvprev = mesh_vert(vm, vprev->index, k, ns - ring);
|
|
||||||
mid_v3_v3v3(co, nv->co, nvprev->co);
|
|
||||||
if (epipe)
|
|
||||||
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
|
|
||||||
|
|
||||||
copy_v3_v3(nv->co, co);
|
|
||||||
BLI_assert(nv->v == NULL && nvprev->v == NULL);
|
|
||||||
create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
|
|
||||||
copy_mesh_vert(vm, vprev->index, k, ns - ring, i, ring, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!vprev->prev->ebev) {
|
|
||||||
for (ring = 1; ring <= ns2; ring++) {
|
|
||||||
for (k = 1; k <= ns2; k++) {
|
|
||||||
if (!odd && (k == ns2 || ring == ns2))
|
|
||||||
continue;
|
|
||||||
create_mesh_bmvert(bm, vm, vprev->index, ring, k, bv->v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!vnext->ebev) {
|
|
||||||
for (ring = 1; ring <= ns2; ring++) {
|
|
||||||
for (k = ns - ns2; k < ns; k++) {
|
|
||||||
if (!odd && (k == ns2 || ring == ns2))
|
|
||||||
continue;
|
|
||||||
create_mesh_bmvert(bm, vm, i, ring, k, bv->v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
|
|
||||||
if (!odd) {
|
|
||||||
/* Do special case center lines.
|
|
||||||
* This loop makes verts for (i, ns2, k) for 1 <= k <= ns-1, k!=ns2
|
|
||||||
* and for (i, r, ns2) for 1 <= r <= ns2-1,
|
|
||||||
* whenever i is in a sequence of at least two beveled verts */
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
if (v->ebev) {
|
|
||||||
vprev = v->prev;
|
|
||||||
vnext = v->next;
|
|
||||||
for (k = 1; k < ns2; k++) {
|
|
||||||
nv = mesh_vert(vm, i, k, ns2);
|
|
||||||
if (vprev->ebev)
|
|
||||||
nvprev = mesh_vert(vm, vprev->index, ns2, ns - k);
|
|
||||||
if (vnext->ebev)
|
|
||||||
nvnext = mesh_vert(vm, vnext->index, ns2, k);
|
|
||||||
if (vprev->ebev && vnext->ebev) {
|
|
||||||
mid_v3_v3v3v3(co, nvprev->co, nv->co, nvnext->co);
|
|
||||||
if (epipe)
|
|
||||||
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
|
|
||||||
copy_v3_v3(nv->co, co);
|
|
||||||
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
|
|
||||||
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
|
|
||||||
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (vprev->ebev) {
|
|
||||||
mid_v3_v3v3(co, nvprev->co, nv->co);
|
|
||||||
if (epipe)
|
|
||||||
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
|
|
||||||
copy_v3_v3(nv->co, co);
|
|
||||||
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
|
|
||||||
copy_mesh_vert(vm, vprev->index, ns2, ns - k, i, k, ns2);
|
|
||||||
|
|
||||||
create_mesh_bmvert(bm, vm, i, ns2, ns - k, bv->v);
|
|
||||||
}
|
|
||||||
else if (vnext->ebev) {
|
|
||||||
mid_v3_v3v3(co, nv->co, nvnext->co);
|
|
||||||
if (epipe)
|
|
||||||
snap_to_edge_profile(epipe, va_pipe, vb_pipe, co);
|
|
||||||
copy_v3_v3(nv->co, co);
|
|
||||||
create_mesh_bmvert(bm, vm, i, k, ns2, bv->v);
|
|
||||||
copy_mesh_vert(vm, vnext->index, ns2, k, i, k, ns2);
|
|
||||||
|
|
||||||
create_mesh_bmvert(bm, vm, i, ns2, k, bv->v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
|
|
||||||
/* center point need to be average of all centers of rings */
|
|
||||||
/* TODO: this is wrong if not all verts have ebev: could have
|
|
||||||
* several disconnected sections of mesh. */
|
|
||||||
zero_v3(midco);
|
|
||||||
nn = 0;
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
if (v->ebev) {
|
|
||||||
nv = mesh_vert(vm, i, ns2, ns2);
|
|
||||||
add_v3_v3(midco, nv->co);
|
|
||||||
nn++;
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
mul_v3_fl(midco, 1.0f / nn);
|
|
||||||
if (epipe)
|
|
||||||
snap_to_edge_profile(epipe, va_pipe, vb_pipe, midco);
|
|
||||||
bmv = BM_vert_create(bm, midco, NULL, BM_CREATE_NOP);
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
if (v->ebev) {
|
|
||||||
nv = mesh_vert(vm, i, ns2, ns2);
|
|
||||||
copy_v3_v3(nv->co, midco);
|
|
||||||
nv->v = bmv;
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the ring quads */
|
|
||||||
for (ring = 0; ring < ns2; ring++) {
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
f = boundvert_rep_face(v);
|
|
||||||
f2 = boundvert_rep_face(v->next);
|
|
||||||
if (v->ebev && (v->prev->ebev || v->next->ebev)) {
|
|
||||||
for (k = 0; k < ns2 + odd; k++) {
|
|
||||||
bmv1 = mesh_vert(vm, i, ring, k)->v;
|
|
||||||
bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
|
|
||||||
bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
|
|
||||||
bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
|
|
||||||
BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
|
|
||||||
if (bmv3 == bmv4 || bmv1 == bmv4)
|
|
||||||
bmv4 = NULL;
|
|
||||||
/* f23 is interp face for bmv2 and bmv3 */
|
|
||||||
f23 = f;
|
|
||||||
if (odd && k == ns2 && f2 && !v->any_seam)
|
|
||||||
f23 = f2;
|
|
||||||
bev_create_quad_tri_ex(bm, bmv1, bmv2, bmv3, bmv4,
|
|
||||||
f, f23, f23, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (v->prev->ebev && v->prev->prev->ebev) {
|
|
||||||
/* finish off a sequence of beveled edges */
|
|
||||||
i = v->prev->index;
|
|
||||||
f = boundvert_rep_face(v->prev);
|
|
||||||
f2 = boundvert_rep_face(v);
|
|
||||||
for (k = ns2 + (ns % 2); k < ns; k++) {
|
|
||||||
bmv1 = mesh_vert(vm, i, ring, k)->v;
|
|
||||||
bmv2 = mesh_vert(vm, i, ring, k + 1)->v;
|
|
||||||
bmv3 = mesh_vert(vm, i, ring + 1, k + 1)->v;
|
|
||||||
bmv4 = mesh_vert(vm, i, ring + 1, k)->v;
|
|
||||||
BLI_assert(bmv1 && bmv2 && bmv3 && bmv4);
|
|
||||||
if (bmv2 == bmv3) {
|
|
||||||
bmv3 = bmv4;
|
|
||||||
bmv4 = NULL;
|
|
||||||
}
|
|
||||||
f23 = f;
|
|
||||||
if (odd && k == ns2 && f2 && !v->any_seam)
|
|
||||||
f23 = f2;
|
|
||||||
bev_create_quad_tri_ex(bm, bmv1, bmv2, bmv3, bmv4,
|
|
||||||
f, f23, f23, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fix UVs along center lines if even number of segments */
|
|
||||||
if (!odd) {
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
f = boundvert_rep_face(v);
|
|
||||||
// f2 = boundvert_rep_face(v->next); // UNUSED
|
|
||||||
if (!v->any_seam) {
|
|
||||||
for (ring = 1; ring < ns2; ring++) {
|
|
||||||
BMVert *v_uv = mesh_vert(vm, i, ring, ns2)->v;
|
|
||||||
if (v_uv) {
|
|
||||||
bev_merge_uvs(bm, v_uv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
if (!bv->any_seam)
|
|
||||||
bev_merge_uvs(bm, mesh_vert(vm, 0, ns2, ns2)->v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make center ngon if odd number of segments and fully beveled */
|
|
||||||
if (odd && vm->count == bv->selcount) {
|
|
||||||
BMVert **vv = NULL;
|
|
||||||
BMFace **vf = NULL;
|
|
||||||
BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
|
|
||||||
BLI_array_staticdeclare(vf, BM_DEFAULT_NGON_STACK_SIZE);
|
|
||||||
|
|
||||||
v = vm->boundstart;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
BLI_assert(v->ebev);
|
|
||||||
BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v);
|
|
||||||
BLI_array_append(vf, bv->any_seam ? f : boundvert_rep_face(v));
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
f = boundvert_rep_face(vm->boundstart);
|
|
||||||
bev_create_ngon(bm, vv, BLI_array_count(vv), vf, f, true);
|
|
||||||
|
|
||||||
BLI_array_free(vv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make 'rest-of-vmesh' polygon if not fully beveled */
|
|
||||||
/* TODO: use interpolation face array here too */
|
|
||||||
if (vm->count > bv->selcount) {
|
|
||||||
int j;
|
|
||||||
BMVert **vv = NULL;
|
|
||||||
BLI_array_staticdeclare(vv, BM_DEFAULT_NGON_STACK_SIZE);
|
|
||||||
|
|
||||||
v = vm->boundstart;
|
|
||||||
f = boundvert_rep_face(v);
|
|
||||||
j = 0;
|
|
||||||
do {
|
|
||||||
i = v->index;
|
|
||||||
if (v->ebev) {
|
|
||||||
if (!v->prev->ebev) {
|
|
||||||
for (k = 0; k < ns2; k++) {
|
|
||||||
bmv1 = mesh_vert(vm, i, ns2, k)->v;
|
|
||||||
if (!bmv1)
|
|
||||||
bmv1 = mesh_vert(vm, i, 0, k)->v;
|
|
||||||
if (!(j > 0 && bmv1 == vv[j - 1])) {
|
|
||||||
BLI_assert(bmv1 != NULL);
|
|
||||||
BLI_array_append(vv, bmv1);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bmv1 = mesh_vert(vm, i, ns2, ns2)->v;
|
|
||||||
if (!bmv1)
|
|
||||||
bmv1 = mesh_vert(vm, i, 0, ns2)->v;
|
|
||||||
if (!(j > 0 && bmv1 == vv[j - 1])) {
|
|
||||||
BLI_assert(bmv1 != NULL);
|
|
||||||
BLI_array_append(vv, bmv1);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (!v->next->ebev) {
|
|
||||||
for (k = ns - ns2; k < ns; k++) {
|
|
||||||
bmv1 = mesh_vert(vm, i, ns2, k)->v;
|
|
||||||
if (!bmv1)
|
|
||||||
bmv1 = mesh_vert(vm, i, 0, k)->v;
|
|
||||||
if (!(j > 0 && bmv1 == vv[j - 1])) {
|
|
||||||
BLI_assert(bmv1 != NULL);
|
|
||||||
BLI_array_append(vv, bmv1);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BLI_assert(mesh_vert(vm, i, 0, 0)->v != NULL);
|
|
||||||
BLI_array_append(vv, mesh_vert(vm, i, 0, 0)->v);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
|
||||||
if (vv[0] == vv[j - 1])
|
|
||||||
j--;
|
|
||||||
bev_create_ngon(bm, vv, j, NULL, f, true);
|
|
||||||
|
|
||||||
BLI_array_free(vv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static VMesh *new_adj_subdiv_vmesh(MemArena *mem_arena, int count, int seg, BoundVert *bounds)
|
|
||||||
{
|
{
|
||||||
VMesh *vm;
|
VMesh *vm;
|
||||||
|
|
||||||
@ -2111,7 +1678,7 @@ static VMesh *new_adj_subdiv_vmesh(MemArena *mem_arena, int count, int seg, Boun
|
|||||||
vm->seg = seg;
|
vm->seg = seg;
|
||||||
vm->boundstart = bounds;
|
vm->boundstart = bounds;
|
||||||
vm->mesh = (NewVert *)BLI_memarena_alloc(mem_arena, count * (1 + seg / 2) * (1 + seg) * sizeof(NewVert));
|
vm->mesh = (NewVert *)BLI_memarena_alloc(mem_arena, count * (1 + seg / 2) * (1 + seg) * sizeof(NewVert));
|
||||||
vm->mesh_kind = M_ADJ_SUBDIV;
|
vm->mesh_kind = M_ADJ;
|
||||||
return vm;
|
return vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2316,7 +1883,7 @@ static VMesh *interp_vmesh(BevelParams *bp, VMesh *vm0, int nseg)
|
|||||||
ns0 = vm0->seg;
|
ns0 = vm0->seg;
|
||||||
nseg2 = nseg / 2;
|
nseg2 = nseg / 2;
|
||||||
odd = nseg % 2;
|
odd = nseg % 2;
|
||||||
vm1 = new_adj_subdiv_vmesh(bp->mem_arena, n, nseg, vm0->boundstart);
|
vm1 = new_adj_vmesh(bp->mem_arena, n, nseg, vm0->boundstart);
|
||||||
|
|
||||||
prev_frac = BLI_array_alloca(prev_frac, (ns0 + 1));
|
prev_frac = BLI_array_alloca(prev_frac, (ns0 + 1));
|
||||||
frac = BLI_array_alloca(frac, (ns0 + 1));
|
frac = BLI_array_alloca(frac, (ns0 + 1));
|
||||||
@ -2388,7 +1955,7 @@ static VMesh *cubic_subdiv(BevelParams *bp, VMesh *vm0)
|
|||||||
ns20 = ns0 / 2;
|
ns20 = ns0 / 2;
|
||||||
BLI_assert(ns0 % 2 == 0);
|
BLI_assert(ns0 % 2 == 0);
|
||||||
ns1 = 2 * ns0;
|
ns1 = 2 * ns0;
|
||||||
vm1 = new_adj_subdiv_vmesh(bp->mem_arena, n, ns1, vm0->boundstart);
|
vm1 = new_adj_vmesh(bp->mem_arena, n, ns1, vm0->boundstart);
|
||||||
|
|
||||||
/* First we adjust the boundary vertices of the input mesh, storing in output mesh */
|
/* First we adjust the boundary vertices of the input mesh, storing in output mesh */
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
@ -2551,7 +2118,7 @@ static VMesh *make_cube_corner_straight(MemArena *mem_arena, int nseg)
|
|||||||
int i, j, k, ns2;
|
int i, j, k, ns2;
|
||||||
|
|
||||||
ns2 = nseg / 2;
|
ns2 = nseg / 2;
|
||||||
vm = new_adj_subdiv_vmesh(mem_arena, 3, nseg, NULL);
|
vm = new_adj_vmesh(mem_arena, 3, nseg, NULL);
|
||||||
vm->count = 0; // reset, so following loop will end up with correct count
|
vm->count = 0; // reset, so following loop will end up with correct count
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
zero_v3(co);
|
zero_v3(co);
|
||||||
@ -2594,7 +2161,7 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
|
|||||||
return make_cube_corner_straight(mem_arena, nseg);
|
return make_cube_corner_straight(mem_arena, nseg);
|
||||||
|
|
||||||
/* initial mesh has 3 sides, 2 segments */
|
/* initial mesh has 3 sides, 2 segments */
|
||||||
vm0 = new_adj_subdiv_vmesh(mem_arena, 3, 2, NULL);
|
vm0 = new_adj_vmesh(mem_arena, 3, 2, NULL);
|
||||||
vm0->count = 0; // reset, so following loop will end up with correct count
|
vm0->count = 0; // reset, so following loop will end up with correct count
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
zero_v3(co);
|
zero_v3(co);
|
||||||
@ -2725,7 +2292,7 @@ static VMesh *adj_vmesh(BevelParams *bp, BevVert *bv)
|
|||||||
/* First construct an initial control mesh, with nseg==2 */
|
/* First construct an initial control mesh, with nseg==2 */
|
||||||
n = bv->vmesh->count;
|
n = bv->vmesh->count;
|
||||||
ns = bv->vmesh->seg;
|
ns = bv->vmesh->seg;
|
||||||
vm0 = new_adj_subdiv_vmesh(mem_arena, n, 2, bv->vmesh->boundstart);
|
vm0 = new_adj_vmesh(mem_arena, n, 2, bv->vmesh->boundstart);
|
||||||
|
|
||||||
bndv = vm0->boundstart;
|
bndv = vm0->boundstart;
|
||||||
zero_v3(co);
|
zero_v3(co);
|
||||||
@ -2810,9 +2377,9 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, EdgeHalf *epipe)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Given that the boundary is built and the boundary BMVerts have been made,
|
* Given that the boundary is built and the boundary BMVerts have been made,
|
||||||
* calculate the positions of the interior mesh points for the M_ADJ_SUBDIV pattern,
|
* calculate the positions of the interior mesh points for the M_ADJ pattern,
|
||||||
* using cubic subdivision, then make the BMVerts and the new faces. */
|
* using cubic subdivision, then make the BMVerts and the new faces. */
|
||||||
static void bevel_build_rings_subdiv(BevelParams *bp, BMesh *bm, BevVert *bv)
|
static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv)
|
||||||
{
|
{
|
||||||
int n, ns, ns2, odd, i, j, k, ring;
|
int n, ns, ns2, odd, i, j, k, ring;
|
||||||
VMesh *vm1, *vm;
|
VMesh *vm1, *vm;
|
||||||
@ -3073,36 +2640,14 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
|
|||||||
do {
|
do {
|
||||||
i = v->index;
|
i = v->index;
|
||||||
copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
|
copy_mesh_vert(vm, i, 0, ns, v->next->index, 0, 0);
|
||||||
#ifdef USE_ADJ_SUBDIV
|
|
||||||
for (k = 1; k < ns; k++) {
|
for (k = 1; k < ns; k++) {
|
||||||
if (v->ebev && vm->mesh_kind != M_ADJ_SUBDIV) {
|
if (v->ebev && vm->mesh_kind != M_ADJ) {
|
||||||
get_profile_point(bp, &v->profile, k, ns, co);
|
get_profile_point(bp, &v->profile, k, ns, co);
|
||||||
copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
|
copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
|
||||||
if (!weld)
|
if (!weld)
|
||||||
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
|
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (v->ebev) {
|
|
||||||
float midco[3];
|
|
||||||
|
|
||||||
va = mesh_vert(vm, i, 0, 0)->co;
|
|
||||||
vb = mesh_vert(vm, i, 0, ns)->co;
|
|
||||||
if (bv->edgecount == 3 && bv->selcount == 1) {
|
|
||||||
/* special case: profile cuts the third face, so line it up with that */
|
|
||||||
copy_v3_v3(midco, bv->v->co);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
project_to_edge(v->ebev->e, va, vb, midco);
|
|
||||||
}
|
|
||||||
for (k = 1; k < ns; k++) {
|
|
||||||
get_point_on_round_edge(v->ebev, k, va, midco, vb, co);
|
|
||||||
copy_v3_v3(mesh_vert(vm, i, 0, k)->co, co);
|
|
||||||
if (!weld)
|
|
||||||
create_mesh_bmvert(bm, vm, i, 0, k, bv->v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} while ((v = v->next) != vm->boundstart);
|
} while ((v = v->next) != vm->boundstart);
|
||||||
|
|
||||||
if (weld) {
|
if (weld) {
|
||||||
@ -3140,12 +2685,7 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
|
|||||||
bevel_build_poly(bm, bv);
|
bevel_build_poly(bm, bv);
|
||||||
break;
|
break;
|
||||||
case M_ADJ:
|
case M_ADJ:
|
||||||
#ifndef USE_ADJ_SUBDIV
|
bevel_build_rings(bp, bm, bv);
|
||||||
bevel_build_rings(bm, bv);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case M_ADJ_SUBDIV:
|
|
||||||
bevel_build_rings_subdiv(bp, bm, bv);
|
|
||||||
break;
|
break;
|
||||||
case M_TRI_FAN:
|
case M_TRI_FAN:
|
||||||
bevel_build_trifan(bm, bv);
|
bevel_build_trifan(bm, bv);
|
||||||
@ -3447,7 +2987,7 @@ static int bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
|
|||||||
BLI_array_append(vv_fix, bmv);
|
BLI_array_append(vv_fix, bmv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vm->mesh_kind == M_ADJ_SUBDIV && vm->seg > 1 && !e->is_bev && !eprev->is_bev) {
|
else if (vm->mesh_kind == M_ADJ && vm->seg > 1 && !e->is_bev && !eprev->is_bev) {
|
||||||
BLI_assert(v->prev == vend);
|
BLI_assert(v->prev == vend);
|
||||||
i = vend->index;
|
i = vend->index;
|
||||||
for (k = vm->seg - 1; k > 0; k--) {
|
for (k = vm->seg - 1; k > 0; k--) {
|
||||||
|
Loading…
Reference in New Issue
Block a user