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:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user