diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-02-11 15:04:16 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2006-02-11 15:04:16 +0300 |
commit | 11adcb6cf28bddadf2bb40db3b64dccc6cc61690 (patch) | |
tree | 0b2fdd35b0c0031b3a0c8790923906e2470fec18 /source/blender/src/parametrizer.c | |
parent | c85abd748f652dccda6ed5ebf6f9f631a87bafc5 (diff) |
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
Diffstat (limited to 'source/blender/src/parametrizer.c')
-rw-r--r-- | source/blender/src/parametrizer.c | 41 |
1 files 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); + + /* 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 (fac > 0.0f); + 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); } |