Fix T63071: Bevel inconsistent results toggling harden_normals.

Some iterations in bevel were over a hash table, which leads
to possibly different results run-to-run, especially when
loop_slide is enabled. Changed those iters to go over all verts
of BMesh, which leads to consistent order run-to-run.
This commit is contained in:
Howard Trickey
2019-04-01 07:58:34 -04:00
parent dd4108545a
commit 61fa6165df

View File

@@ -2941,18 +2941,24 @@ static void adjust_the_cycle_or_chain(BoundVert *vstart, bool iscycle)
* It turns out that the dependent offsets either form chains or
* cycles, and we can process each of those separatey.
*/
static void adjust_offsets(BevelParams *bp)
static void adjust_offsets(BevelParams *bp, BMesh *bm)
{
BMVert *bmv;
BevVert *bv, *bvcur;
BoundVert *v, *vanchor, *vchainstart, *vchainend, *vnext;
EdgeHalf *enext;
GHashIterator giter;
BMIter iter;
bool iscycle;
int chainlen;
/* find and process chains and cycles of unvisited BoundVerts that have eon set */
GHASH_ITER(giter, bp->vert_hash) {
bv = bvcur = BLI_ghashIterator_getValue(&giter);
/* note: for repeatability, iterate over all verts of mesh rather than over ghash'ed BMVerts */
BM_ITER_MESH(bmv, &iter, bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(bmv, BM_ELEM_TAG))
continue;
bv = bvcur = find_bevvert(bp, bmv);
if (!bv)
continue;
vanchor = bv->vmesh->boundstart;
do {
if (vanchor->visited || !vanchor->eon) {
@@ -3023,9 +3029,12 @@ static void adjust_offsets(BevelParams *bp)
}
/* Rebuild boundaries with new width specs */
GHASH_ITER(giter, bp->vert_hash) {
bv = BLI_ghashIterator_getValue(&giter);
build_boundary(bp, bv, false);
BM_ITER_MESH(bmv, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(bmv, BM_ELEM_TAG)) {
bv = find_bevvert(bp, bmv);
if (bv)
build_boundary(bp, bv, false);
}
}
}
@@ -6275,17 +6284,22 @@ static float vertex_collide_offset(BevelParams *bp, EdgeHalf *ea)
* current edge offset specs to reflect this clamping,
* and store the new offset in bp.offset.
*/
static void bevel_limit_offset(BevelParams *bp)
static void bevel_limit_offset(BevelParams *bp, BMesh *bm)
{
BevVert *bv;
EdgeHalf *eh;
GHashIterator giter;
BMIter iter;
BMVert *bmv;
float limited_offset, offset_factor, collision_offset;
int i;
limited_offset = bp->offset;
GHASH_ITER(giter, bp->vert_hash) {
bv = BLI_ghashIterator_getValue(&giter);
BM_ITER_MESH(bmv, &iter, bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(bmv, BM_ELEM_TAG))
continue;
bv = find_bevvert(bp, bmv);
if (!bv)
continue;
for (i = 0; i < bv->edgecount; i++) {
eh = &bv->edges[i];
if (bp->vertex_only) {
@@ -6310,8 +6324,12 @@ static void bevel_limit_offset(BevelParams *bp)
* with the new limited_offset.
*/
offset_factor = limited_offset / bp->offset;
GHASH_ITER(giter, bp->vert_hash) {
bv = BLI_ghashIterator_getValue(&giter);
BM_ITER_MESH(bmv, &iter, bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(bmv, BM_ELEM_TAG))
continue;
bv = find_bevvert(bp, bmv);
if (!bv)
continue;
for (i = 0; i < bv->edgecount; i++) {
eh = &bv->edges[i];
eh->offset_l_spec *= offset_factor;
@@ -6353,7 +6371,6 @@ void BM_mesh_bevel(
BMLoop *l;
BevVert *bv;
BevelParams bp = {NULL};
GHashIterator giter;
bp.offset = offset;
bp.offset_type = offset_type;
@@ -6404,22 +6421,24 @@ void BM_mesh_bevel(
/* Perhaps clamp offset to avoid geometry colliisions */
if (limit_offset) {
bevel_limit_offset(&bp);
bevel_limit_offset(&bp, bm);
/* Assign initial new vertex positions */
GHASH_ITER(giter, bp.vert_hash) {
bv = BLI_ghashIterator_getValue(&giter);
build_boundary(&bp, bv, true);
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
bv = find_bevvert(&bp, v);
if (bv)
build_boundary(&bp, bv, true);
}
}
}
/* Perhaps do a pass to try to even out widths */
if (!bp.vertex_only && bp.offset_adjust && bp.offset_type != BEVEL_AMT_PERCENT) {
adjust_offsets(&bp);
adjust_offsets(&bp, bm);
}
/* Build the meshes around vertices, now that positions are final */
/* Note: could use GHASH_ITER over bp.vert_hash when backward compatibility no longer matters */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
bv = find_bevvert(&bp, v);
@@ -6439,9 +6458,12 @@ void BM_mesh_bevel(
}
/* Extend edge data like sharp edges and precompute normals for harden */
GHASH_ITER(giter, bp.vert_hash) {
bv = BLI_ghashIterator_getValue(&giter);
bevel_extend_edge_data(bv);
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
bv = find_bevvert(&bp, v);
if (bv)
bevel_extend_edge_data(bv);
}
}
/* Rebuild face polygons around affected vertices */