[Bf-blender-cvs] [939b993600c] soc-2019-bevel-profiles: Custom Profile Terminal Edge (3 Boundverts): Only use the triangle fill vertex mesh method when the extra vertex is not planar with the profile.
Hans Goudey
noreply at git.blender.org
Mon Jul 29 15:44:32 CEST 2019
Commit: 939b993600c4bf8f554c66c73a918307b9f150b8
Author: Hans Goudey
Date: Mon Jul 29 05:43:26 2019 -0400
Branches: soc-2019-bevel-profiles
https://developer.blender.org/rB939b993600c4bf8f554c66c73a918307b9f150b8
Custom Profile Terminal Edge (3 Boundverts): Only use the triangle
fill vertex mesh method when the extra vertex is not planar with
the profile.
===================================================================
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 564986666b2..5711fde3aaa 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -128,7 +128,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 a path defined with control points coa, midco,
+ * The profile is a path defined with start, middle, and end control points
* 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
@@ -215,13 +215,13 @@ typedef struct BoundVert {
/* Mesh structure replacing a vertex */
typedef struct VMesh {
- /** allocated array - size and structure depends on kind */
+ /** Allocated array - size and structure depends on kind */
NewVert *mesh;
- /** start of boundary double-linked list */
+ /** Start of boundary double-linked list */
BoundVert *boundstart;
- /** number of vertices in the boundary */
+ /** Number of vertices in the boundary */
int count;
- /** common # of segments for segmented edges (same as bp->seg) */
+ /** Common # of segments for segmented edges (same as bp->seg) */
int seg;
/** The kind of mesh to build at the corner vertex meshes */
enum {
@@ -229,7 +229,7 @@ typedef struct VMesh {
M_POLY, /* a simple polygon */
M_ADJ, /* "adjacent edges" mesh pattern */
M_TRI_FAN, /* a simple polygon - fan filled */
- M_CUTOFF, /* A triangulated face at the end of each profile */
+ M_CUTOFF, /* A triangulated face at the end of each vmesh profile */
} mesh_kind;
int _pad;
@@ -875,7 +875,7 @@ static void bev_merge_edge_uvs(BMesh *bm, BMEdge *bme, BMVert *v)
}
/* Calculate coordinates of a point a distance d from v on e->e and return it in slideco */
-static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
+static void slide_dist(EdgeHalf *e, BMVert *v, float d, float r_slideco[3])
{
float dir[3], len;
@@ -884,8 +884,8 @@ static void slide_dist(EdgeHalf *e, BMVert *v, float d, float slideco[3])
if (d > len) {
d = len - (float)(50.0 * BEVEL_EPSILON_D);
}
- copy_v3_v3(slideco, v->co);
- madd_v3_v3fl(slideco, dir, -d);
+ copy_v3_v3(r_slideco, v->co);
+ madd_v3_v3fl(r_slideco, dir, -d);
}
/* Is co not on the edge e? if not, return the closer end of e in ret_closer_v */
@@ -980,7 +980,7 @@ static bool point_between_edges(float co[3], BMVert *v, BMFace *f, EdgeHalf *e1,
/*
* Calculate the meeting point between the offset edges for e1 and e2, putting answer in meetco.
* e1 and e2 share vertex v and face f (may be NULL) and viewed from the normal side of
- * the bevel vertex, e1 precedes e2 in CCW order.
+ * the bevel vertex, e1 precedes e2 in CCW order.
* Except: if edges_between is true, there are edges between e1 and e2 in CCW order so they
* don't share a common face. We want the meeting point to be on an existing face so it
* should be dropped onto one of the intermediate faces, if possible.
@@ -2354,12 +2354,10 @@ static void build_boundary_vertex_only(BevelParams *bp, BevVert *bv, bool constr
* The 'width adjust' part of build_boundary has been done already,
* and \a efirst is the first beveled edge at vertex \a bv.
*/
-/* HANS-TODO: Don't use the TRI_FAN mesh type for custom profiles because the overhangs can cause
- * artifacts */
static void build_boundary_terminal_edge(BevelParams *bp,
BevVert *bv,
EdgeHalf *efirst,
- bool construct)
+ const bool construct)
{
MemArena *mem_arena = bp->mem_arena;
VMesh *vm = bv->vmesh;
@@ -2367,6 +2365,7 @@ static void build_boundary_terminal_edge(BevelParams *bp,
EdgeHalf *e;
const float *no;
float co[3], d;
+ bool use_tri_fan;
e = efirst;
if (bv->edgecount == 2) {
@@ -2397,8 +2396,6 @@ static void build_boundary_terminal_edge(BevelParams *bp,
bndv = add_new_bound_vert(mem_arena, vm, co);
bndv->efirst = bndv->elast = e->next;
e->next->leftv = e->next->rightv = bndv;
- /* could use M_POLY too, but tri-fan looks nicer)*/
- vm->mesh_kind = M_TRI_FAN;
set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp);
}
else {
@@ -2435,6 +2432,12 @@ static void build_boundary_terminal_edge(BevelParams *bp,
}
/* For the edges not adjacent to the beveled edge, slide the bevel amount along. */
d = efirst->offset_l_spec;
+ if (bp->use_custom_profile) {
+ /* HANS-TODO: Even this doesn't give enough room to the profile when the adjacent edges
+ * aren't square so the profile is rotated sideways. There are already issues with this when
+ * the non-custom profile parameter is small though */
+ d *= sqrtf(2.0f); /* Need to go further down the edge to make room for full profile area */
+ }
for (e = e->next; e->next != efirst; e = e->next) {
slide_dist(e, bv->v, d, co);
if (construct) {
@@ -2445,6 +2448,7 @@ static void build_boundary_terminal_edge(BevelParams *bp,
else {
adjust_bound_vert(e->leftv, co);
}
+
}
}
calculate_vm_profiles(bp, bv, vm);
@@ -2456,6 +2460,7 @@ static void build_boundary_terminal_edge(BevelParams *bp,
move_profile_plane(bndv, bv->v);
/* This step happens before profile orientation regularization, so don't reverse the profile */
calculate_profile(bp, bndv, false, false);
+
}
if (construct) {
@@ -2465,7 +2470,18 @@ static void build_boundary_terminal_edge(BevelParams *bp,
vm->mesh_kind = M_NONE;
}
else if (vm->count == 3) {
- vm->mesh_kind = M_TRI_FAN;
+ use_tri_fan = true;
+ if (bp->use_custom_profile) {
+ /* Use M_POLY if the extra point is planar with the profile to prevent overhanging edges */
+ bndv = efirst->leftv;
+ float profile_plane[4];
+ plane_from_point_normal_v3(profile_plane, bndv->profile.plane_co, bndv->profile.plane_no);
+ bndv = efirst->rightv->next; /* The added boundvert placed along the non-adjacent edge */
+ if (dist_squared_to_plane_v3(bndv->nv.co, profile_plane) < BEVEL_EPSILON_BIG) {
+ use_tri_fan = false;
+ }
+ }
+ vm->mesh_kind = (use_tri_fan) ? M_TRI_FAN : M_POLY;
}
else {
vm->mesh_kind = M_POLY;
@@ -2604,7 +2620,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
BLI_assert(e->is_bev);
if (bv->selcount == 1) {
- /* special case: only one beveled edge in */
+ /* Special case: only one beveled edge in */
build_boundary_terminal_edge(bp, bv, efirst, construct);
return;
}
More information about the Bf-blender-cvs
mailing list