From 11adcb6cf28bddadf2bb40db3b64dccc6cc61690 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 11 Feb 2006 12:04:16 +0000 Subject: [PATCH] ABF Fix: With two adjacent quads sharing three vertices, splitting to triangles could create duplicate triangles. This broke unwrapping of Suzanne near the nose, where there is a sort of t-joint with quads that isn't really a t-joint. Now works fine: http://users.pandora.be/blendix/suzanne.png --- source/blender/src/parametrizer.c | 41 ++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/source/blender/src/parametrizer.c b/source/blender/src/parametrizer.c index 043ece74523..50fa6dc1220 100644 --- a/source/blender/src/parametrizer.c +++ b/source/blender/src/parametrizer.c @@ -545,6 +545,27 @@ static PEdge *p_edge_lookup(PHandle *handle, PHashKey *vkeys) return NULL; } +static PBool p_face_exists(PHandle *handle, PHashKey *vkeys, int i1, int i2, int i3) +{ + PHashKey key = PHASH_edge(vkeys[i1], vkeys[i2]); + PEdge *e = (PEdge*)phash_lookup(handle->hash_edges, key); + + while (e) { + if ((e->vert->u.key == vkeys[i1]) && (e->next->vert->u.key == vkeys[i2])) { + if (e->next->next->vert->u.key == vkeys[i3]) + return P_TRUE; + } + else if ((e->vert->u.key == vkeys[i2]) && (e->next->vert->u.key == vkeys[i1])) { + if (e->next->next->vert->u.key == vkeys[i3]) + return P_TRUE; + } + + e = (PEdge*)phash_next(handle->hash_edges, key, (PHashLink*)e); + } + + return P_FALSE; +} + static PChart *p_chart_new(PHandle *handle) { PChart *chart = (PChart*)MEM_callocN(sizeof*chart, "PChart"); @@ -894,11 +915,25 @@ static PFace *p_face_add_fill(PChart *chart, PVert *v1, PVert *v2, PVert *v3) return f; } -static PBool p_quad_split_direction(float **co) +static PBool p_quad_split_direction(PHandle *handle, float **co, PHashKey *vkeys) { float fac= VecLenf(co[0], co[2]) - VecLenf(co[1], co[3]); + PBool dir = (fac <= 0.0f); - return (fac > 0.0f); + /* the face exists check is there because of a special case: when + two quads share three vertices, they can each be split into two + triangles, resulting in two identical triangles. for example in + suzanne's nose. */ + if (dir) { + if (p_face_exists(handle,vkeys,0,1,2) || p_face_exists(handle,vkeys,0,2,3)) + return !dir; + } + else { + if (p_face_exists(handle,vkeys,0,1,3) || p_face_exists(handle,vkeys,1,2,3)) + return !dir; + } + + return dir; } /* Construction: boundary filling */ @@ -3985,7 +4020,7 @@ void param_face_add(ParamHandle *handle, ParamKey key, int nverts, param_assert((nverts == 3) || (nverts == 4)); if (nverts == 4) { - if (!p_quad_split_direction(co)) { + if (p_quad_split_direction(phandle, co, vkeys)) { p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 2, pin, select); p_face_add_construct(phandle, key, vkeys, co, uv, 0, 2, 3, pin, select); }