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;
}
case GraphicsWindow::MNU_ORIENTED_SAME:
case GraphicsWindow::MNU_ORIENTED_SAME: {
if(gs.anyNormals == 2 && gs.n == 2) {
c.type = SAME_ORIENTATION;
c.entityA = gs.anyNormal[0];
@ -315,8 +315,36 @@ void Constraint::MenuConstrain(int id) {
Error("Bad selection for same orientation constraint.");
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;
}
case GraphicsWindow::MNU_OTHER_ANGLE:
if(gs.constraints == 1 && gs.n == 0) {

View File

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