bmesh inset: another small improvement - use the shared edge vector rather then the cross product between 2 faces if the faces infact share an edge - works best for non planer faces.

also added utility function - BM_loop_other_vert_loop
This commit is contained in:
Campbell Barton
2012-03-25 14:44:48 +00:00
parent 105c282b9f
commit fffe342d87
3 changed files with 72 additions and 6 deletions

View File

@@ -151,6 +151,56 @@ BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v)
}
}
/**
* \brief Other Loop in Face Sharing a Vert
*
* Finds the other loop that shares \a v with \a e loop in \a f.
*
* +----------+ <-- return the face loop of this vertex.
* | |
* | |
* | |
* +----------+ <-- This vertex defines the direction.
* l v
* ^ <------- This loop defines both the face to search
* and the edge, in combination with 'v'
* The faces loop direction is ignored.
*/
BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v)
{
#if 0 /* works but slow */
return BM_face_other_vert_loop(l->f, BM_edge_other_vert(l->e, v), v);
#else
BMEdge *e = l->e;
BMVert *v_prev = BM_edge_other_vert(e, v);
if (l->v == v) {
if (l->prev->v == v_prev) {
return l->next;
}
else {
BLI_assert(l->next->v == v_prev);
return l->prev;
}
}
else {
BLI_assert(l->v == v_prev);
if (l->prev->v == v) {
return l->prev->prev;
}
else {
BLI_assert(l->next->v == v);
return l->next->next;
}
}
#endif
}
/**
* Returns TRUE if the vertex is used in a given face.
*/

View File

@@ -43,6 +43,7 @@ int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb);
BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v);
BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v);
BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v);
BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v);
int BM_vert_edge_count_nonwire(BMVert *v);
int BM_vert_edge_count(BMVert *v);

View File

@@ -274,7 +274,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
* if both edges use the same face OR both faces have the same normal,
* ...then we can calculate an edge that fits nicely between the 2 edge normals.
*
* Otherwise use the corner defined by these 2 edge-face normals,
* Otherwise use the shared edge OR the corner defined by these 2 face normals,
* when both edges faces are adjacent this works best but even when this vertex
* fans out faces it should work ok.
*/
@@ -293,12 +293,27 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
normalize_v3(tvec);
}
else {
float tno[3];
cross_v3_v3v3(tno, f_a->no, f_b->no);
if (dot_v3v3(tvec, tno) < 0.0f) {
negate_v3(tno);
/* these lookups are very quick */
BMLoop *l_other_a = BM_loop_other_vert_loop(e_info_a->l, v_split);
BMLoop *l_other_b = BM_loop_other_vert_loop(e_info_b->l, v_split);
if (l_other_a->v == l_other_b->v) {
/* both edges faces are adjacent, but we don't need to know the shared edge
* having both verts is enough. */
sub_v3_v3v3(tvec, l_other_a->v->co, v_split->co);
}
copy_v3_v3(tvec, tno);
else {
/* faces don't touch,
* just get cross product of their normals, its *good enough*
*/
float tno[3];
cross_v3_v3v3(tno, f_a->no, f_b->no);
if (dot_v3v3(tvec, tno) < 0.0f) {
negate_v3(tno);
}
copy_v3_v3(tvec, tno);
}
normalize_v3(tvec);
}