knife sort_by_frac_along was re-calculating the reference factor for every test, change to only calculate once and use line_point_factor_v3().

also add zero division check for line_point_factor_v3() since the 2d version already checked for this.
This commit is contained in:
Campbell Barton 2013-05-03 05:57:33 +00:00
parent a5d6820b6d
commit 2a78a14369
2 changed files with 15 additions and 23 deletions

@ -1654,9 +1654,16 @@ float closest_to_line_v2(float cp[2], const float p[2], const float l1[2], const
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]) float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
{ {
float h[3], u[3]; float h[3], u[3];
float dot;
sub_v3_v3v3(u, l2, l1); sub_v3_v3v3(u, l2, l1);
sub_v3_v3v3(h, p, l1); sub_v3_v3v3(h, p, l1);
#if 0
return (dot_v3v3(u, h) / dot_v3v3(u, u)); return (dot_v3v3(u, h) / dot_v3v3(u, u));
#else
/* better check for zero */
dot = dot_v3v3(u, u);
return (dot != 0.0f) ? (dot_v3v3(u, h) / dot) : 0.0f;
#endif
} }
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]) float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2])

@ -2212,43 +2212,28 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
#else /* use direct (non-scanfill) method for cuts */ #else /* use direct (non-scanfill) method for cuts */
/* assuming v is on line ab, what fraction of the way is v from a to b? */
static float frac_along(const float a[3], const float b[3], const float v[3])
{
float lab;
lab = len_v3v3(a, b);
if (lab == 0.0f) {
return 0.0f;
}
else {
return len_v3v3(a, v) / lab;
}
}
/* sort list of kverts by fraction along edge e */ /* sort list of kverts by fraction along edge e */
static void sort_by_frac_along(ListBase *lst, BMEdge *e) static void sort_by_frac_along(ListBase *lst, BMEdge *e)
{ {
KnifeVert *vcur, *vprev; const float *v1co = e->v1->co;
float *v1co, *v2co; const float *v2co = e->v2->co;
Ref *cur = NULL, *prev = NULL, *next = NULL; Ref *cur = NULL, *prev = NULL, *next = NULL;
if (lst->first == lst->last) if (lst->first == lst->last)
return; return;
v1co = e->v1->co;
v2co = e->v2->co;
for (cur = ((Ref *)lst->first)->next; cur; cur = next) { for (cur = ((Ref *)lst->first)->next; cur; cur = next) {
KnifeVert *vcur = cur->ref;
const float vcur_fac = line_point_factor_v3(vcur->co, v1co, v2co);
next = cur->next; next = cur->next;
prev = cur->prev; prev = cur->prev;
BLI_remlink(lst, cur); BLI_remlink(lst, cur);
vcur = cur->ref;
while (prev) { while (prev) {
vprev = prev->ref; KnifeVert *vprev = prev->ref;
if (frac_along(v1co, v2co, vprev->co) <= frac_along(v1co, v2co, vcur->co)) if (line_point_factor_v3(vprev->co, v1co, v2co) <= vcur_fac)
break; break;
prev = prev->prev; prev = prev->prev;
} }
@ -2860,7 +2845,7 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
sort_by_frac_along(lst, e); sort_by_frac_along(lst, e);
for (ref = lst->first; ref; ref = ref->next) { for (ref = lst->first; ref; ref = ref->next) {
kfv = ref->ref; kfv = ref->ref;
pct = frac_along(e->v1->co, e->v2->co, kfv->co); pct = line_point_factor_v3(kfv->co, e->v1->co, e->v2->co);
kfv->v = BM_edge_split(bm, e, e->v1, &enew, pct); kfv->v = BM_edge_split(bm, e, e->v1, &enew, pct);
} }
} }