Commit: fad9b5c4e42af937f21dca34dd3a541e47d44a70 Author: Hans Goudey Date: Fri Jul 19 22:14:09 2019 -0400 Branches: soc-2019-bevel-profiles https://developer.blender.org/rBfad9b5c4e42af937f21dca34dd3a541e47d44a70
Bevel Tool Cut-Off Method: Mostly working implementation This is the first implementation of the cut-off vertex mesh method which just creates an N-gon at the end of each profile. There are a few items that need to be finished, but the structure is working/complete: 1. The direction and length from the boundary vertices to the cut-off faces' corner vertices. 2. Representative "example" faces for the new ngons. =================================================================== M source/blender/bmesh/tools/bmesh_bevel.c =================================================================== diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 12a86adf5b6..8a957b4762e 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -63,6 +63,7 @@ #define DEBUG_CUSTOM_PROFILE_ADJ 0 #define DEBUG_CUSTOM_PROFILE_ORIENTATION 0 #define DEBUG_CUSTOM_PROFILE_ORIENTATION_DRAW DEBUG_CUSTOM_PROFILE_ORIENTATION | 0 +#define DEBUG_CUSTOM_PROFILE_CUTOFF 1 #if DEBUG_CUSTOM_PROFILE_ORIENTATION_DRAW extern void DRW_debug_sphere(const float center[3], const float radius, const float color[4]); @@ -86,22 +87,38 @@ struct BoundVert; /* Data for one end of an edge involved in a bevel */ typedef struct EdgeHalf { - struct EdgeHalf *next, *prev; /* in CCW order */ - BMEdge *e; /* original mesh edge */ - BMFace *fprev; /* face between this edge and previous, if any */ - BMFace *fnext; /* face between this edge and next, if any */ - struct BoundVert *leftv; /* left boundary vert (looking along edge to end) */ - struct BoundVert *rightv; /* right boundary vert, if beveled */ - int profile_index; /* offset into profile to attach non-beveled edge */ - int seg; /* how many segments for the bevel */ - float offset_l; /* offset for this edge, on left side */ - float offset_r; /* offset for this edge, on right side */ - float offset_l_spec; /* user specification for offset_l */ - float offset_r_spec; /* user specification for offset_r */ - bool is_bev; /* is this edge beveled? */ - bool is_rev; /* is e->v2 the vertex at this end? */ - bool is_seam; /* is e a seam for custom loopdata (e.g., UVs)? */ - bool visited_custom; /* Used during the custom profile orientation pass */ + /** In CCW order */ + struct EdgeHalf *next, *prev; + /** Original mesh edge */ + BMEdge *e; + /** Face between this edge and previous, if any */ + BMFace *fprev; + /** Face between this edge and next, if any */ + BMFace *fnext; + /** Left boundary vert (looking along edge to end) */ + struct BoundVert *leftv; + /** Right boundary vert, if beveled */ + struct BoundVert *rightv; + /** Offset into profile to attach non-beveled edge */ + int profile_index; + /** How many segments for the bevel */ + int seg; + /** Offset for this edge, on left side */ + float offset_l; + /** Offset for this edge, on right side */ + float offset_r; + /** User specification for offset_l */ + float offset_l_spec; + /** User specification for offset_r */ + float offset_r_spec; + /** Is this edge beveled? */ + bool is_bev; + /** Is e->v2 the vertex at this end? */ + bool is_rev; + /** Is e a seam for custom loopdata (e.g., UVs)? */ + bool is_seam; + /** Used during the custom profile orientation pass */ + bool visited_custom; char _pad[4]; } EdgeHalf; @@ -110,7 +127,7 @@ typedef struct EdgeHalf { * (abs(x/a))^r + abs(y/b))^r = 1 * r==2 => ellipse; r==1 => line; r < 1 => concave; r > 1 => bulging out. * Special cases: let r==0 mean straight-inward, and r==4 mean straight outward. - * The profile is an arc with control points coa, midco, + * The profile is a path defined with control points coa, midco, * projected onto a plane (plane_no is normal, plane_co is a point on it) * via lines in a given direction (proj_dir). * After the parameters are all set, the actual profile points are calculated @@ -119,16 +136,25 @@ typedef struct EdgeHalf { * in prof_co_2. */ typedef struct Profile { - float super_r; /* superellipse r parameter */ - float coa[3]; /* start control point for profile */ - float midco[3]; /* mid control point for profile */ - float cob[3]; /* end control point for profile */ - float plane_no[3]; /* normal of plane to project to */ - float plane_co[3]; /* coordinate on plane to project to */ - float proj_dir[3]; /* direction of projection line */ + /** Superellipse r parameter */ + float super_r; + /** Start control point for profile */ + float coa[3]; + /** Mid control point for profile */ + float midco[3]; + /** End control point for profile */ + float cob[3]; + /** Normal of plane to project to */ + float plane_no[3]; + /** Coordinate on plane to project to */ + float plane_co[3]; + /** Direction of projection line */ + float proj_dir[3]; int _pad; - float *prof_co; /* seg+1 profile coordinates (triples of floats) */ - float *prof_co_2; /* like prof_co, but for seg power of 2 >= seg */ + /** seg+1 profile coordinates (triples of floats) */ + float *prof_co; + /** Like prof_co, but for seg power of 2 >= seg */ + float *prof_co_2; } Profile; #define PRO_SQUARE_R 1e4f #define PRO_CIRCLE_R 2.0f @@ -186,10 +212,15 @@ typedef struct BoundVert { /* Mesh structure replacing a vertex */ typedef struct VMesh { - NewVert *mesh; /* allocated array - size and structure depends on kind */ - BoundVert *boundstart; /* start of boundary double-linked list */ - int count; /* number of vertices in the boundary */ - int seg; /* common # of segments for segmented edges (same as bp->seg) */ + /** allocated array - size and structure depends on kind */ + NewVert *mesh; + /** start of boundary double-linked list */ + BoundVert *boundstart; + /** number of vertices in the boundary */ + int count; + /** common # of segments for segmented edges (same as bp->seg) */ + int seg; + /** The kind of mesh to build at the corner vertex meshes */ enum { M_NONE, /* no polygon mesh needed */ M_POLY, /* a simple polygon */ @@ -231,7 +262,7 @@ typedef enum { F_NONE, /** Original face, not touched */ F_ORIG, - /** Face for construction aroun a vert */ + /** Face for construction around a vert */ F_VERT, /** Face for a beveled edge */ F_EDGE, @@ -253,7 +284,6 @@ typedef struct BevelParams { MemArena *mem_arena; /** Parameter values for evenly spaced profiles. */ ProfileSpacing pro_spacing; - /** Blender units to offset each side of a beveled edge. */ float offset; /** How offset is measured; enum defined in bmesh_operators.h */ @@ -1410,8 +1440,7 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv) * original beveled vert, bmv. This will usually be the plane containing its adjacent * non-beveled edges, but sometimes coa and cob are not on those edges. * - * Currently just used in build boundary terminal edge - */ + * Currently just used in build boundary terminal edge */ static void move_profile_plane(BoundVert *bndv, BMVert *bmv) { float d1[3], d2[3], no[3], no2[3], no3[3], dot2, dot3; @@ -2317,7 +2346,7 @@ static void build_boundary_vertex_only(BevelParams *bp, BevVert *bv, bool constr * and \a efirst is the first beveled edge at vertex \a bv. */ /* HANS-TODO: In the TRI_FAN fill case, check if the third point is planar with the other two - * boundverts. If it is, then use polyfill operation on the face instead of a TRI_FAN. When they + * boundverts. If it is, then use ngon operation on the face instead of a TRI_FAN. When they * are planar the overlapping geometry used to fill the profile if it overlaps itself looks bad */ static void build_boundary_terminal_edge(BevelParams *bp, BevVert *bv, @@ -3376,7 +3405,7 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle) /* Use the solution to set new widths */ v = vstart; i = 0; - do {k + do { val = EIG_linear_solver_variable_get(solver, 0, i); if (iscycle || i < np - 1) { eright = v->efirst; @@ -3576,6 +3605,9 @@ static BoundVert *pipe_test(BevVert *bv) static VMesh *new_adj_vmesh(MemArena *mem_arena, int count, int seg, BoundVert *bounds) { +#if DEBUG_CUSTOM_PROFILE_CUTOFF + printf("NEW ADJ VMESH\n"); +#endif VMesh *vm; vm = (VMesh *)BLI_memarena_alloc(mem_arena, sizeof(VMesh)); @@ -3812,40 +3844,34 @@ static int interp_range(const float *frac, int n, const float f, float *r_rest) } /* Interpolate given vmesh to make one with target nseg border vertices on the profiles */ -/* HANS-TODO: Needs custom analog. */ -/* HANS-QUESTION: So it looks this resamples the mesh at the correct nseg. Because its whole method - * is about sampling even spaces along the profile, it looks like I'll need to make an entirely - * new function for the same purpose in the profile space. But it also could be that I can use - * the distances along the rings that are built to control how much of which profile is sampled - * This process here is the biggest remaining unknown. */ -static VMesh *interp_vmesh(BevelParams *bp, VMesh *vm0, int nseg) +static VMesh *interp_vmesh(BevelParams *bp, VMesh *vm_in, int nseg) { #if DEBUG_CUSTOM_PROFILE_ADJ printf("INTERP VMESH\n"); #endif - int n_verts, ns0, nseg2, odd, i, j, k, j0, k0, k0prev, j0inc, k0inc; + int n_bndv, ns0, nseg2, odd, i, j, k, j0, k0, k0prev, j0inc, k0inc; float *prev_frac, *frac, *new_frac, *prev_new_frac; float f, restj, restk, restkprev; float quad[4][3], co[3], center[3]; - VMesh *vm1; + VMesh *vm_out; BoundVert *bndv; - n_verts = vm0->count; - ns0 = vm0->seg; + n_bndv = vm_in->count; + ns0 = vm_in->seg; nseg2 = nseg / 2; odd = nseg % 2; - vm1 = new_adj_vmesh(bp->mem_arena, n_verts, nseg, vm0->boundstart); + vm_out = new_adj_vmesh(bp->mem_arena, n_bndv, nseg, vm_in->boundstart); prev_frac = BLI_array_alloca(prev_frac, (ns0 + 1)); frac = BLI_array_alloca(frac, (ns0 + 1)); new_frac = BLI_array_alloca(new_frac, (nseg + 1)); prev_new_frac = BLI_array_alloca(prev_new_frac, (nseg + 1)); - fill_vmesh_fracs(vm0, prev_frac, n_verts - 1); - bndv = vm0->boundstart; + fill_vmesh_fracs(vm_in, prev_frac, n_bndv - 1); + bndv = vm_in->boundstart; fill_profile_fracs(bp, bndv->prev, prev_new_frac, nseg); - for (i = 0; i < n_verts; i++) { - fill_vmesh_fracs(vm0, frac, i); + for (i = 0; i < n_bndv; i++) { + fill_vmesh_fracs(vm_in, frac, i); fill_profile_fracs(bp, bndv, new_frac, nseg); for (j = 0; j <= nseg2 - 1 + odd; j++) { f @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs