diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-03-25 12:20:19 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-03-25 12:20:19 +0400 |
commit | 3b711a6ed009b35bb69cd0ca878eeb8d55fa0e77 (patch) | |
tree | b3fdb366cb49bdea5b57dfa6ba4a82635c68d0ee /source/blender/bmesh/intern/bmesh_queries.c | |
parent | a2ebfc82dbe954acc432ae017ac62a30a11b6a16 (diff) | |
parent | e99a23fc6b33b5097eab44aac19c2a089ddebce6 (diff) |
Merged changes in the trunk up to revision 45133.
Conflicts resolved:
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/intern/bmesh_mesh_conv.c
source/blender/bmesh/intern/bmesh_mesh_conv.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/resources.c
source/blender/editors/mesh/bmesh_select.c
source/blender/editors/mesh/bmesh_tools.c
source/blender/editors/space_view3d/drawobject.c
source/blender/render/intern/source/shadeoutput.c
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_queries.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 156 |
1 files changed, 134 insertions, 22 deletions
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index e6dc1e1dd80..8f1568119f8 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -259,6 +259,14 @@ BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v) } /** + * Returms edge length + */ +float BM_edge_length_calc(BMEdge *e) +{ + return len_v3v3(e->v1->co, e->v2->co); +} + +/** * Utility function, since enough times we have an edge * and want to access 2 connected faces. * @@ -284,6 +292,31 @@ int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb) } /** + * Utility function, since enough times we have an edge + * and want to access 2 connected loops. + * + * \return TRUE when only 2 faces are found. + */ +int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb) +{ + BMLoop *la, *lb; + + if ((la = e->l) && + (lb = la->radial_next) && + (lb->radial_next == la)) + { + *r_la = la; + *r_lb = lb; + return TRUE; + } + else { + *r_la = NULL; + *r_lb = NULL; + return FALSE; + } +} + +/** * Returns the number of edges around this vertex. */ int BM_vert_edge_count(BMVert *v) @@ -291,6 +324,18 @@ int BM_vert_edge_count(BMVert *v) return bmesh_disk_count(v); } +int BM_vert_edge_count_nonwire(BMVert *v) +{ + int count = 0; + BMIter eiter; + BMEdge *edge; + BM_ITER(edge, &eiter, NULL, BM_EDGES_OF_VERT, v) { + if (edge->l) { + count++; + } + } + return count; +} /** * Returns the number of faces around this edge */ @@ -344,7 +389,7 @@ int BM_vert_face_count(BMVert *v) * Tests whether or not the vertex is part of a wire edge. * (ie: has no faces attached to it) */ -int BM_vert_is_wire(BMesh *UNUSED(bm), BMVert *v) +int BM_vert_is_wire(BMVert *v) { BMEdge *curedge; @@ -368,7 +413,7 @@ int BM_vert_is_wire(BMesh *UNUSED(bm), BMVert *v) * Tests whether or not the edge is part of a wire. * (ie: has no faces attached to it) */ -int BM_edge_is_wire(BMesh *UNUSED(bm), BMEdge *e) +int BM_edge_is_wire(BMEdge *e) { return (e->l) ? FALSE : TRUE; } @@ -380,7 +425,7 @@ int BM_edge_is_wire(BMesh *UNUSED(bm), BMEdge *e) * 3: Is part of a non-manifold edge (edge with more than 2 faces) * 4: Is part of a wire edge */ -int BM_vert_is_manifold(BMesh *UNUSED(bm), BMVert *v) +int BM_vert_is_manifold(BMVert *v) { BMEdge *e, *oe; BMLoop *l; @@ -446,14 +491,14 @@ int BM_vert_is_manifold(BMesh *UNUSED(bm), BMVert *v) */ #if 1 /* fast path for checking manifold */ -int BM_edge_is_manifold(BMesh *UNUSED(bm), BMEdge *e) +int BM_edge_is_manifold(BMEdge *e) { const BMLoop *l = e->l; return (l && ((l->radial_next == l) || /* 1 face user */ (l->radial_next->radial_next == l))); /* 2 face users */ } #else -int BM_edge_is_manifold(BMesh *UNUSED(bm), BMEdge *e) +int BM_edge_is_manifold(BMEdge *e) { int count = BM_edge_face_count(e); if (count == 2 || count == 1) { @@ -470,7 +515,7 @@ int BM_edge_is_manifold(BMesh *UNUSED(bm), BMEdge *e) * of a shell (has one face associated with it) */ -#if 1 /* fast path for checking boundry */ +#if 1 /* fast path for checking boundary */ int BM_edge_is_boundary(BMEdge *e) { const BMLoop *l = e->l; @@ -583,15 +628,18 @@ BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v) * Returns the verts of an edge as used in a face * if used in a face at all, otherwise just assign as used in the edge. * - * Useful to get a determanistic winding order when calling + * Useful to get a deterministic winding order when calling * BM_face_create_ngon() on an arbitrary array of verts, * though be sure to pick an edge which has a face. */ -void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2) +void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2, + BMLoop *edge_loop) { - if ((edge->l == NULL) || - (((edge->l->prev->v == edge->v1) && (edge->l->v == edge->v2)) || - ((edge->l->v == edge->v1) && (edge->l->next->v == edge->v2))) + BLI_assert(edge_loop->e == edge); + + if ((edge_loop == NULL) || + (((edge_loop->prev->v == edge->v1) && (edge_loop->v == edge->v2)) || + ((edge_loop->v == edge->v1) && (edge_loop->next->v == edge->v2))) ) { *r_v1 = edge->v1; @@ -603,13 +651,18 @@ void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2) } } +void BM_edge_ordered_verts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2) +{ + BM_edge_ordered_verts_ex(edge, r_v1, r_v2, edge->l); +} + /** * Calculates the angle between the previous and next loops * (angle at this loops face corner). * * \return angle in radians */ -float BM_loop_face_angle(BMesh *UNUSED(bm), BMLoop *l) +float BM_loop_face_angle(BMLoop *l) { return angle_v3v3v3(l->prev->v->co, l->v->co, @@ -617,6 +670,65 @@ float BM_loop_face_angle(BMesh *UNUSED(bm), BMLoop *l) } /** + * \brief BM_loop_face_normal + * + * Calculate the normal at this loop corner or fallback to the face normal on straignt lines. + * + * \param bm The BMesh + * \param l The loop to calculate the normal at + * \param r_normal Resulting normal + */ +void BM_loop_face_normal(BMLoop *l, float r_normal[3]) +{ + if (normal_tri_v3(r_normal, + l->prev->v->co, + l->v->co, + l->next->v->co) != 0.0f) + { + return; + } + else { + copy_v3_v3(r_normal, l->f->no); + } +} + +/** + * \brief BM_loop_face_tangent + * + * Calculate the tangent at this loop corner or fallback to the face normal on straignt lines. + * This vector always points inward into the face. + * + * \param bm The BMesh + * \param l The loop to calculate the tangent at + * \param r_tangent Resulting tangent + */ +void BM_loop_face_tangent(BMLoop *l, float r_tangent[3]) +{ + float v_prev[3]; + float v_next[3]; + + sub_v3_v3v3(v_prev, l->prev->v->co, l->v->co); + sub_v3_v3v3(v_next, l->v->co, l->next->v->co); + + normalize_v3(v_prev); + normalize_v3(v_next); + + if (compare_v3v3(v_prev, v_next, FLT_EPSILON) == FALSE) { + float dir[3]; + float nor[3]; /* for this purpose doesnt need to be normalized */ + add_v3_v3v3(dir, v_prev, v_next); + cross_v3_v3v3(nor, v_prev, v_next); + cross_v3_v3v3(r_tangent, dir, nor); + } + else { + /* prev/next are the same - compare with face normal since we don't have one */ + cross_v3_v3v3(r_tangent, v_next, l->f->no); + } + + normalize_v3(r_tangent); +} + +/** * \brief BMESH EDGE/FACE ANGLE * * Calculates the angle between two faces. @@ -624,7 +736,7 @@ float BM_loop_face_angle(BMesh *UNUSED(bm), BMLoop *l) * * \return angle in radians */ -float BM_edge_face_angle(BMesh *UNUSED(bm), BMEdge *e) +float BM_edge_face_angle(BMEdge *e) { if (BM_edge_face_count(e) == 2) { BMLoop *l1 = e->l; @@ -643,7 +755,7 @@ float BM_edge_face_angle(BMesh *UNUSED(bm), BMEdge *e) * * \returns the angle in radians */ -float BM_vert_edge_angle(BMesh *UNUSED(bm), BMVert *v) +float BM_vert_edge_angle(BMVert *v) { BMEdge *e1, *e2; @@ -790,7 +902,7 @@ int BM_face_exists_multi(BMesh *bm, BMVert **varr, BMEdge **earr, int len) } } - /* now tag all verts and edges in the boundry array as true so + /* now tag all verts and edges in the boundary array as true so * we can know if a face-vert is from our array */ for (i = 0; i < len; i++) { BM_elem_flag_enable(varr[i], BM_ELEM_INTERNAL_TAG); @@ -798,10 +910,10 @@ int BM_face_exists_multi(BMesh *bm, BMVert **varr, BMEdge **earr, int len) } - /* so! boundry is tagged, everything else cleared */ + /* so! boundary is tagged, everything else cleared */ - /* 1) tag all faces connected to edges - if all their verts are boundry */ + /* 1) tag all faces connected to edges - if all their verts are boundary */ tot_tag = 0; for (i = 0; i < len; i++) { BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, earr[i]) { @@ -815,7 +927,7 @@ int BM_face_exists_multi(BMesh *bm, BMVert **varr, BMEdge **earr, int len) } if (ok) { - /* we only use boundry verts */ + /* we only use boundary verts */ BM_elem_flag_enable(f, BM_ELEM_INTERNAL_TAG); tot_tag++; } @@ -827,19 +939,19 @@ int BM_face_exists_multi(BMesh *bm, BMVert **varr, BMEdge **earr, int len) } if (tot_tag == 0) { - /* no faces use only boundry verts, quit early */ + /* no faces use only boundary verts, quit early */ return FALSE; } - /* 2) loop over non-boundry edges that use boundry verts, + /* 2) loop over non-boundary edges that use boundary verts, * check each have 2 tagges faces connected (faces that only use 'varr' verts) */ ok = TRUE; for (i = 0; i < len; i++) { BM_ITER(e, &fiter, bm, BM_EDGES_OF_VERT, varr[i]) { - if (/* non-boundry edge */ + if (/* non-boundary edge */ BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == FALSE && - /* ...using boundry verts */ + /* ...using boundary verts */ BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) == TRUE && BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG) == TRUE) { |