Force the numerical guess for a normal to be exactly correct when a

same orientation constraint is applied; this makes convergence
easy. And don't hover faces or constraints while dragging
something.

[git-p4: depot-paths = "//depot/solvespace/": change = 1798]
solver
Jonathan Westhues 2008-06-18 01:18:51 -08:00
parent ae566f0380
commit 89bb81b35c
2 changed files with 49 additions and 17 deletions

View File

@ -306,7 +306,7 @@ void Constraint::MenuConstrain(int id) {
break; break;
} }
case GraphicsWindow::MNU_ORIENTED_SAME: case GraphicsWindow::MNU_ORIENTED_SAME: {
if(gs.anyNormals == 2 && gs.n == 2) { if(gs.anyNormals == 2 && gs.n == 2) {
c.type = SAME_ORIENTATION; c.type = SAME_ORIENTATION;
c.entityA = gs.anyNormal[0]; c.entityA = gs.anyNormal[0];
@ -315,8 +315,36 @@ void Constraint::MenuConstrain(int id) {
Error("Bad selection for same orientation constraint."); Error("Bad selection for same orientation constraint.");
return; return;
} }
AddConstraint(&c); SS.UndoRemember();
Entity *nfree = SS.GetEntity(c.entityA);
Entity *nref = SS.GetEntity(c.entityB);
if(nref->group.v == SS.GW.activeGroup.v) {
SWAP(Entity *, nref, nfree);
}
if(nfree->group.v == SS.GW.activeGroup.v &&
nref ->group.v != SS.GW.activeGroup.v)
{
// nfree is free, and nref is locked (since it came from a
// previous group); so let's force nfree aligned to nref,
// and make convergence easy
Vector ru = nref ->NormalU(), rv = nref ->NormalV();
Vector fu = nfree->NormalU(), fv = nfree->NormalV();
if(fabs(fu.Dot(ru)) < fabs(fu.Dot(rv))) {
// There might be an odd*90 degree rotation about the
// normal vector; allow that, since the numerical
// constraint does
SWAP(Vector, ru, rv);
}
fu = fu.Dot(ru) > 0 ? ru : ru.ScaledBy(-1);
fv = fv.Dot(rv) > 0 ? rv : rv.ScaledBy(-1);
nfree->NormalForceTo(Quaternion::From(fu, fv));
}
AddConstraint(&c, false);
break; break;
}
case GraphicsWindow::MNU_OTHER_ANGLE: case GraphicsWindow::MNU_OTHER_ANGLE:
if(gs.constraints == 1 && gs.n == 0) { if(gs.constraints == 1 && gs.n == 0) {

View File

@ -775,7 +775,8 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
Selection s; Selection s;
ZERO(&s); ZERO(&s);
// Do the entities // Always do the entities; we might be dragging something that should
// be auto-constrained, and we need the hover for that.
for(i = 0; i < SS.entity.n; i++) { for(i = 0; i < SS.entity.n; i++) {
Entity *e = &(SS.entity.elem[i]); Entity *e = &(SS.entity.elem[i]);
// Don't hover whatever's being dragged. // Don't hover whatever's being dragged.
@ -789,22 +790,25 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
} }
} }
// Constraints // The constraints and faces happen only when nothing's in progress.
for(i = 0; i < SS.constraint.n; i++) { if(pending.operation == 0) {
d = SS.constraint.elem[i].GetDistance(mp); // Constraints
if(d < 10 && d < dmin) { for(i = 0; i < SS.constraint.n; i++) {
memset(&s, 0, sizeof(s)); d = SS.constraint.elem[i].GetDistance(mp);
s.constraint = SS.constraint.elem[i].h; if(d < 10 && d < dmin) {
dmin = d; memset(&s, 0, sizeof(s));
s.constraint = SS.constraint.elem[i].h;
dmin = d;
}
} }
}
// Faces, from the triangle mesh; these are lowest priority // Faces, from the triangle mesh; these are lowest priority
if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) { if(s.constraint.v == 0 && s.entity.v == 0 && showShaded && showFaces) {
SMesh *m = &((SS.GetGroup(activeGroup))->mesh); SMesh *m = &((SS.GetGroup(activeGroup))->mesh);
DWORD v = m->FirstIntersectionWith(mp); DWORD v = m->FirstIntersectionWith(mp);
if(v) { if(v) {
s.entity.v = v; s.entity.v = v;
}
} }
} }