Now we can add new workplanes. So fix all the mistakes that I
hadn't previously noticed, because I didn't use to have workplanes with non-zero offsets. And clean up the interface to normals a bit. [git-p4: depot-paths = "//depot/solvespace/": change = 1707]
This commit is contained in:
parent
d048946adc
commit
c767d55c71
|
@ -64,7 +64,7 @@ void Constraint::MenuConstrain(int id) {
|
|||
c.type = POINTS_COINCIDENT;
|
||||
c.ptA = gs.point[0];
|
||||
c.ptB = gs.point[1];
|
||||
} else if(gs.points == 1 && gs.planes == 1 && gs.n == 2) {
|
||||
} else if(gs.points == 1 && gs.workplanes == 1 && gs.n == 2) {
|
||||
c.type = PT_IN_PLANE;
|
||||
c.ptA = gs.point[0];
|
||||
c.entityA = gs.entity[0];
|
||||
|
@ -96,9 +96,9 @@ void Constraint::MenuConstrain(int id) {
|
|||
c.type = AT_MIDPOINT;
|
||||
c.entityA = gs.entity[0];
|
||||
c.ptA = gs.point[0];
|
||||
} else if(gs.lineSegments == 1 && gs.planes == 1 && gs.n == 2) {
|
||||
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
|
||||
c.type = AT_MIDPOINT;
|
||||
int i = SS.GetEntity(gs.entity[0])->HasPlane() ? 1 : 0;
|
||||
int i = SS.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
|
||||
c.entityA = gs.entity[i];
|
||||
c.entityB = gs.entity[1-i];
|
||||
} else {
|
||||
|
@ -109,14 +109,14 @@ void Constraint::MenuConstrain(int id) {
|
|||
break;
|
||||
|
||||
case GraphicsWindow::MNU_SYMMETRIC:
|
||||
if(gs.points == 2 && gs.planes == 1 && gs.n == 3) {
|
||||
if(gs.points == 2 && gs.workplanes == 1 && gs.n == 3) {
|
||||
c.type = SYMMETRIC;
|
||||
c.entityA = gs.entity[0];
|
||||
c.ptA = gs.point[0];
|
||||
c.ptB = gs.point[1];
|
||||
} else if(gs.lineSegments == 1 && gs.planes == 1 && gs.n == 2) {
|
||||
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
|
||||
c.type = SYMMETRIC;
|
||||
int i = SS.GetEntity(gs.entity[0])->HasPlane() ? 1 : 0;
|
||||
int i = SS.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
|
||||
Entity *line = SS.GetEntity(gs.entity[i]);
|
||||
c.entityA = gs.entity[1-i];
|
||||
c.ptA = line->point[0];
|
||||
|
@ -239,7 +239,7 @@ Expr *Constraint::PointLineDistance(hEntity wrkpl, hEntity hpt, hEntity hln) {
|
|||
Expr *Constraint::PointPlaneDistance(ExprVector p, hEntity hpl) {
|
||||
ExprVector n;
|
||||
Expr *d;
|
||||
SS.GetEntity(hpl)->PlaneGetExprs(&n, &d);
|
||||
SS.GetEntity(hpl)->WorkplaneGetPlaneExprs(&n, &d);
|
||||
return (p.Dot(n))->Minus(d);
|
||||
}
|
||||
|
||||
|
@ -271,10 +271,11 @@ Expr *Constraint::Distance(hEntity wrkpl, hEntity hpa, hEntity hpb) {
|
|||
}
|
||||
|
||||
ExprVector Constraint::PointInThreeSpace(hEntity workplane, Expr *u, Expr *v) {
|
||||
ExprVector ub, vb, ob;
|
||||
Entity *w = SS.GetEntity(workplane);
|
||||
w->WorkplaneGetBasisExprs(&ub, &vb);
|
||||
ob = w->WorkplaneGetOffsetExprs();
|
||||
|
||||
ExprVector ub = w->Normal()->NormalExprsU();
|
||||
ExprVector vb = w->Normal()->NormalExprsV();
|
||||
ExprVector ob = w->WorkplaneGetOffsetExprs();
|
||||
|
||||
return (ub.ScaledBy(u)).Plus(vb.ScaledBy(v)).Plus(ob);
|
||||
}
|
||||
|
@ -441,15 +442,15 @@ void Constraint::Generate(IdList<Equation,hEquation> *l) {
|
|||
// to the symmetry pane's normal (i.e., that lies in the
|
||||
// plane of symmetry). The line connecting the points is
|
||||
// perpendicular to that constructed vector.
|
||||
ExprVector u, v;
|
||||
Entity *w = SS.GetEntity(workplane);
|
||||
w->WorkplaneGetBasisExprs(&u, &v);
|
||||
ExprVector u = w->Normal()->NormalExprsU();
|
||||
ExprVector v = w->Normal()->NormalExprsV();
|
||||
|
||||
ExprVector pa = a->PointGetExprs();
|
||||
ExprVector pb = b->PointGetExprs();
|
||||
ExprVector n;
|
||||
Expr *d;
|
||||
plane->PlaneGetExprs(&n, &d);
|
||||
plane->WorkplaneGetPlaneExprs(&n, &d);
|
||||
AddEq(l, (n.Cross(u.Cross(v))).Dot(pa.Minus(pb)), 1);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -132,7 +132,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|||
case SYMMETRIC: {
|
||||
Vector a = SS.GetEntity(ptA)->PointGetNum();
|
||||
Vector b = SS.GetEntity(ptB)->PointGetNum();
|
||||
Vector n = SS.GetEntity(entityA)->WorkplaneGetNormalVector();
|
||||
Vector n = SS.GetEntity(entityA)->Normal()->NormalN();
|
||||
for(int i = 0; i < 2; i++) {
|
||||
Vector tail = (i == 0) ? a : b;
|
||||
Vector d = (i == 0) ? b : a;
|
||||
|
@ -161,7 +161,8 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|||
if(workplane.v == Entity::FREE_IN_3D.v) {
|
||||
r = gr; u = gu; n = gn;
|
||||
} else {
|
||||
SS.GetEntity(workplane)->WorkplaneGetBasisVectors(&r, &u);
|
||||
r = SS.GetEntity(workplane)->Normal()->NormalU();
|
||||
u = SS.GetEntity(workplane)->Normal()->NormalV();
|
||||
n = r.Cross(u);
|
||||
}
|
||||
// For "at midpoint", this branch is always taken.
|
||||
|
@ -193,9 +194,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos) {
|
|||
Vector b = SS.GetEntity(ptB)->PointGetNum();
|
||||
|
||||
Entity *w = SS.GetEntity(SS.GetEntity(ptA)->workplane);
|
||||
Vector cu, cv, cn;
|
||||
w->WorkplaneGetBasisVectors(&cu, &cv);
|
||||
cn = w->WorkplaneGetNormalVector();
|
||||
Vector cu = w->Normal()->NormalU();
|
||||
Vector cv = w->Normal()->NormalV();
|
||||
Vector cn = w->Normal()->NormalN();
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 2; i++) {
|
||||
|
|
87
entity.cpp
87
entity.cpp
|
@ -5,44 +5,21 @@ char *Entity::DescriptionString(void) {
|
|||
return r->DescriptionString();
|
||||
}
|
||||
|
||||
void Entity::WorkplaneGetBasisVectors(Vector *u, Vector *v) {
|
||||
Quaternion quat = SS.GetEntity(normal)->NormalGetNum();
|
||||
|
||||
*u = quat.RotationU();
|
||||
*v = quat.RotationV();
|
||||
}
|
||||
|
||||
Vector Entity::WorkplaneGetNormalVector(void) {
|
||||
Vector u, v;
|
||||
WorkplaneGetBasisVectors(&u, &v);
|
||||
return u.Cross(v);
|
||||
}
|
||||
|
||||
void Entity::WorkplaneGetBasisExprs(ExprVector *u, ExprVector *v) {
|
||||
ExprQuaternion q = SS.GetEntity(normal)->NormalGetExprs();
|
||||
|
||||
*u = q.RotationU();
|
||||
*v = q.RotationV();
|
||||
bool Entity::IsWorkplane(void) {
|
||||
return (type == WORKPLANE);
|
||||
}
|
||||
|
||||
ExprVector Entity::WorkplaneGetOffsetExprs(void) {
|
||||
return SS.GetEntity(point[0])->PointGetExprs();
|
||||
}
|
||||
|
||||
bool Entity::HasPlane(void) {
|
||||
switch(type) {
|
||||
case WORKPLANE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
Vector Entity::WorkplaneGetOffset(void) {
|
||||
return SS.GetEntity(point[0])->PointGetNum();
|
||||
}
|
||||
|
||||
void Entity::PlaneGetExprs(ExprVector *n, Expr **dn) {
|
||||
void Entity::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) {
|
||||
if(type == WORKPLANE) {
|
||||
ExprQuaternion q = (SS.GetEntity(normal))->NormalGetExprs();
|
||||
// Convert the quaternion to our plane's normal vector.
|
||||
*n = q.RotationN();
|
||||
*n = Normal()->NormalExprsN();
|
||||
|
||||
ExprVector p0 = SS.GetEntity(point[0])->PointGetExprs();
|
||||
// The plane is n dot (p - p0) = 0, or
|
||||
|
@ -54,6 +31,10 @@ void Entity::PlaneGetExprs(ExprVector *n, Expr **dn) {
|
|||
}
|
||||
}
|
||||
|
||||
Entity *Entity::Normal(void) {
|
||||
return SS.GetEntity(normal);
|
||||
}
|
||||
|
||||
bool Entity::IsPoint(void) {
|
||||
switch(type) {
|
||||
case POINT_IN_3D:
|
||||
|
@ -117,6 +98,26 @@ void Entity::NormalForceTo(Quaternion q) {
|
|||
}
|
||||
}
|
||||
|
||||
Vector Entity::NormalU(void) {
|
||||
return NormalGetNum().RotationU();
|
||||
}
|
||||
Vector Entity::NormalV(void) {
|
||||
return NormalGetNum().RotationV();
|
||||
}
|
||||
Vector Entity::NormalN(void) {
|
||||
return NormalGetNum().RotationN();
|
||||
}
|
||||
|
||||
ExprVector Entity::NormalExprsU(void) {
|
||||
return NormalGetExprs().RotationU();
|
||||
}
|
||||
ExprVector Entity::NormalExprsV(void) {
|
||||
return NormalGetExprs().RotationV();
|
||||
}
|
||||
ExprVector Entity::NormalExprsN(void) {
|
||||
return NormalGetExprs().RotationN();
|
||||
}
|
||||
|
||||
ExprQuaternion Entity::NormalGetExprs(void) {
|
||||
ExprQuaternion q;
|
||||
switch(type) {
|
||||
|
@ -159,10 +160,9 @@ void Entity::PointForceTo(Vector p) {
|
|||
|
||||
case POINT_IN_2D: {
|
||||
Entity *c = SS.GetEntity(workplane);
|
||||
Vector u, v;
|
||||
c->WorkplaneGetBasisVectors(&u, &v);
|
||||
SS.GetParam(param[0])->val = p.Dot(u);
|
||||
SS.GetParam(param[1])->val = p.Dot(v);
|
||||
p = p.Minus(c->WorkplaneGetOffset());
|
||||
SS.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU());
|
||||
SS.GetParam(param[1])->val = p.Dot(c->Normal()->NormalV());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -189,10 +189,11 @@ Vector Entity::PointGetNum(void) {
|
|||
|
||||
case POINT_IN_2D: {
|
||||
Entity *c = SS.GetEntity(workplane);
|
||||
Vector u, v;
|
||||
c->WorkplaneGetBasisVectors(&u, &v);
|
||||
Vector u = c->Normal()->NormalU();
|
||||
Vector v = c->Normal()->NormalV();
|
||||
p = u.ScaledBy(SS.GetParam(param[0])->val);
|
||||
p = p.Plus(v.ScaledBy(SS.GetParam(param[1])->val));
|
||||
p = p.Plus(c->WorkplaneGetOffset());
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -219,10 +220,10 @@ ExprVector Entity::PointGetExprs(void) {
|
|||
|
||||
case POINT_IN_2D: {
|
||||
Entity *c = SS.GetEntity(workplane);
|
||||
ExprVector u, v;
|
||||
c->WorkplaneGetBasisExprs(&u, &v);
|
||||
|
||||
r = u.ScaledBy(Expr::FromParam(param[0]));
|
||||
ExprVector u = c->Normal()->NormalExprsU();
|
||||
ExprVector v = c->Normal()->NormalExprsV();
|
||||
r = c->WorkplaneGetOffsetExprs();
|
||||
r = r.Plus(u.ScaledBy(Expr::FromParam(param[0])));
|
||||
r = r.Plus(v.ScaledBy(Expr::FromParam(param[1])));
|
||||
break;
|
||||
}
|
||||
|
@ -253,8 +254,8 @@ void Entity::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) {
|
|||
// Get the offset and basis vectors for this weird exotic csys.
|
||||
Entity *w = SS.GetEntity(wrkpl);
|
||||
ExprVector wp = w->WorkplaneGetOffsetExprs();
|
||||
ExprVector wu, wv;
|
||||
w->WorkplaneGetBasisExprs(&wu, &wv);
|
||||
ExprVector wu = w->Normal()->NormalExprsU();
|
||||
ExprVector wv = w->Normal()->NormalExprsV();
|
||||
|
||||
// Get our coordinates in three-space, and project them into that
|
||||
// coordinate system.
|
||||
|
@ -404,8 +405,8 @@ void Entity::DrawOrGetDistance(int order) {
|
|||
Vector p;
|
||||
p = SS.GetEntity(point[0])->PointGetNum();
|
||||
|
||||
Vector u, v;
|
||||
WorkplaneGetBasisVectors(&u, &v);
|
||||
Vector u = Normal()->NormalU();
|
||||
Vector v = Normal()->NormalV();
|
||||
|
||||
double s = (min(SS.GW.width, SS.GW.height))*0.4/SS.GW.scale;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
|
|||
{ 1, "Draw Anywhere in 3d\tQ", MNU_FREE_IN_3D, 'Q', mReq },
|
||||
{ 1, NULL, 0, NULL },
|
||||
{ 1, "Datum &Point\tP", MNU_DATUM_POINT, 'P', mReq },
|
||||
{ 1, "&Workplane (Coordinate S&ystem)\tY", 0, 'Y', mReq },
|
||||
{ 1, "&Workplane (Coordinate S&ystem)\tY", MNU_WORKPLANE, 'Y', mReq },
|
||||
{ 1, NULL, 0, NULL },
|
||||
{ 1, "Line &Segment\tS", MNU_LINE_SEGMENT, 'S', mReq },
|
||||
{ 1, "&Rectangle\tR", MNU_RECTANGLE, 'R', mReq },
|
||||
|
@ -137,8 +137,8 @@ Point2d GraphicsWindow::ProjectPoint(Vector p) {
|
|||
|
||||
void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) {
|
||||
// Get our initial orientation and translation.
|
||||
Quaternion quat0 = Quaternion::MakeFrom(SS.GW.projRight, SS.GW.projUp);
|
||||
Vector offset0 = SS.GW.offset;
|
||||
Quaternion quat0 = Quaternion::MakeFrom(projRight, projUp);
|
||||
Vector offset0 = offset;
|
||||
|
||||
// Make sure we take the shorter of the two possible paths.
|
||||
double mp = (quatf.Minus(quat0)).Magnitude();
|
||||
|
@ -147,9 +147,10 @@ void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) {
|
|||
quatf = quatf.ScaledBy(-1);
|
||||
mp = mm;
|
||||
}
|
||||
double mo = (offset0.Minus(offsetf)).Magnitude()/scale;
|
||||
|
||||
// Animate transition, unless it's a tiny move.
|
||||
SDWORD dt = (mp < 0.01) ? (-20) : (SDWORD)(100 + 1000*mp);
|
||||
SDWORD dt = (mp < 0.01 && mo < 10) ? (-20) : (SDWORD)(100 + 1000*mp);
|
||||
SDWORD tn, t0 = GetMilliseconds();
|
||||
double s = 0;
|
||||
do {
|
||||
|
@ -327,12 +328,9 @@ void GraphicsWindow::MenuRequest(int id) {
|
|||
}
|
||||
// Align the view with the selected workplane
|
||||
Entity *e = SS.GetEntity(SS.GW.activeWorkplane);
|
||||
Vector pr, pu;
|
||||
e->WorkplaneGetBasisVectors(&pr, &pu);
|
||||
Quaternion quatf = Quaternion::MakeFrom(pr, pu);
|
||||
Vector offsetf = SS.GetEntity(e->point[0])->PointGetNum();
|
||||
Quaternion quatf = e->Normal()->NormalGetNum();
|
||||
Vector offsetf = (e->WorkplaneGetOffset()).ScaledBy(-1);
|
||||
SS.GW.AnimateOnto(quatf, offsetf);
|
||||
|
||||
SS.GW.EnsureValidActives();
|
||||
SS.TW.Show();
|
||||
break;
|
||||
|
@ -347,6 +345,7 @@ void GraphicsWindow::MenuRequest(int id) {
|
|||
case MNU_LINE_SEGMENT: s = "click first point of line segment"; goto c;
|
||||
case MNU_CUBIC: s = "click first point of cubic segment"; goto c;
|
||||
case MNU_CIRCLE: s = "click center of circle"; goto c;
|
||||
case MNU_WORKPLANE: s = "click origin of workplane"; goto c;
|
||||
c:
|
||||
SS.GW.pending.operation = id;
|
||||
SS.GW.pending.description = s;
|
||||
|
@ -519,8 +518,8 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
|||
u = u.RotatedAbout(normal, -theta);
|
||||
v = v.RotatedAbout(normal, -theta);
|
||||
} else {
|
||||
double dx = (x - orig.mouse.x);
|
||||
double dy = (y - orig.mouse.y);
|
||||
double dx = -(x - orig.mouse.x);
|
||||
double dy = -(y - orig.mouse.y);
|
||||
double s = 0.3*(PI/180); // degrees per pixel
|
||||
u = u.RotatedAbout(orig.projUp, -s*dx);
|
||||
u = u.RotatedAbout(orig.projRight, s*dy);
|
||||
|
@ -621,7 +620,6 @@ void GraphicsWindow::GroupSelection(void) {
|
|||
case Entity::WORKPLANE: (gs.workplanes)++; break;
|
||||
case Entity::LINE_SEGMENT: (gs.lineSegments)++; break;
|
||||
}
|
||||
if(e->HasPlane()) (gs.planes)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -720,6 +718,17 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||
pending.description = "click to place next point of cubic";
|
||||
break;
|
||||
|
||||
case MNU_WORKPLANE:
|
||||
hr = AddRequest(Request::WORKPLANE);
|
||||
SS.GetEntity(hr.entity(1))->PointForceTo(v);
|
||||
SS.GetEntity(hr.entity(16))->NormalForceTo(
|
||||
Quaternion::MakeFrom(SS.GW.projRight, SS.GW.projUp));
|
||||
MAYBE_PLACE(hr.entity(1));
|
||||
|
||||
ClearSelection(); hover.Clear();
|
||||
ClearPending();
|
||||
break;
|
||||
|
||||
case DRAGGING_RADIUS:
|
||||
case DRAGGING_NEW_POINT:
|
||||
// The MouseMoved event has already dragged it as desired.
|
||||
|
|
21
sketch.h
21
sketch.h
|
@ -159,7 +159,7 @@ public:
|
|||
static const int POINT_XFRMD = 2010;
|
||||
|
||||
static const int NORMAL_IN_3D = 3000;
|
||||
static const int NORMAL_COPY = 3001;
|
||||
static const int NORMAL_IN_2D = 3001;
|
||||
// This is a normal that lies in a plane; so if the defining workplane
|
||||
// has basis vectors uw, vw, nw, then
|
||||
// n = (cos theta)*uw + (sin theta)*vw
|
||||
|
@ -192,11 +192,12 @@ public:
|
|||
// times to apply the transformation.
|
||||
int timesApplied;
|
||||
|
||||
// Applies only for a WORKPLANE type
|
||||
void WorkplaneGetBasisVectors(Vector *u, Vector *v);
|
||||
Vector WorkplaneGetNormalVector(void);
|
||||
void WorkplaneGetBasisExprs(ExprVector *u, ExprVector *v);
|
||||
bool IsWorkplane(void);
|
||||
// The plane is points P such that P dot (xn, yn, zn) - d = 0
|
||||
void WorkplaneGetPlaneExprs(ExprVector *n, Expr **d);
|
||||
ExprVector WorkplaneGetOffsetExprs(void);
|
||||
Vector WorkplaneGetOffset(void);
|
||||
Entity *Normal(void);
|
||||
|
||||
bool IsPoint(void);
|
||||
// Applies for any of the point types
|
||||
|
@ -212,10 +213,12 @@ public:
|
|||
ExprQuaternion NormalGetExprs(void);
|
||||
void NormalForceTo(Quaternion q);
|
||||
|
||||
// Applies for anything that comes with a plane
|
||||
bool HasPlane(void);
|
||||
// The plane is points P such that P dot (xn, yn, zn) - d = 0
|
||||
void PlaneGetExprs(ExprVector *n, Expr **d);
|
||||
Vector NormalU(void);
|
||||
Vector NormalV(void);
|
||||
Vector NormalN(void);
|
||||
ExprVector NormalExprsU(void);
|
||||
ExprVector NormalExprsV(void);
|
||||
ExprVector NormalExprsN(void);
|
||||
|
||||
// Routines to draw and hit-test the representation of the entity
|
||||
// on-screen.
|
||||
|
|
Loading…
Reference in New Issue
Block a user