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
parent
ae566f0380
commit
89bb81b35c
|
@ -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) {
|
||||
|
|
34
draw.cpp
34
draw.cpp
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue