Now display dimensions (and stuff in the text window) in the

user-selected units, and enter them the same way.

[git-p4: depot-paths = "//depot/solvespace/": change = 1792]
solver
Jonathan Westhues 2008-06-14 01:51:25 -08:00
parent 28e3f0abab
commit d391c43bff
9 changed files with 107 additions and 59 deletions

View File

@ -555,8 +555,22 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
Vector p3 = c->GetLabelPos();
Point2d p2 = ProjectPoint(p3);
char *s = (c->type == Constraint::COMMENT) ? c->comment.str :
ToString(c->valA);
char s[1024];
switch(c->type) {
case Constraint::COMMENT:
strcpy(s, c->comment.str);
break;
case Constraint::ANGLE:
case Constraint::LENGTH_RATIO:
sprintf(s, "%.3f", c->valA);
break;
default:
strcpy(s, SS.MmToString(fabs(c->valA)));
break;
}
ShowGraphicsEditControl((int)p2.x, (int)p2.y-4, s);
}
}
@ -575,8 +589,33 @@ void GraphicsWindow::EditControlDone(char *s) {
if(e) {
SS.UndoRemember();
c->valA = e->Eval();
switch(c->type) {
case Constraint::PT_LINE_DISTANCE:
case Constraint::PT_FACE_DISTANCE:
case Constraint::PT_PLANE_DISTANCE: {
// The sign is not displayed to the user, but this is a signed
// distance internally. To flip the sign, the user enters a
// negative distance.
bool wasNeg = (c->valA < 0);
if(wasNeg) {
c->valA = -SS.ExprToMm(e);
} else {
c->valA = SS.ExprToMm(e);
}
break;
}
case Constraint::ANGLE:
case Constraint::LENGTH_RATIO:
// These don't get the units conversion for distance, and
// they're always positive
c->valA = fabs(e->Eval());
break;
default:
// These are always positive, and they get the units conversion.
c->valA = fabs(SS.ExprToMm(e));
break;
}
SS.MarkGroupDirty(c->group);
SS.GenerateAll();
} else {

View File

@ -51,7 +51,7 @@ char *Constraint::Label(void) {
strcpy(Ret, comment.str);
} else {
// valA has units of distance
strcpy(Ret, SS.GW.ToString(valA));
strcpy(Ret, SS.MmToString(fabs(valA)));
}
if(reference) {
strcat(Ret, " REF");

View File

@ -117,12 +117,16 @@ bool Entity::IsVisible(void) {
// Don't check if points are hidden; this gets called only for
// selected or hovered points, and those should always be shown.
if(IsWorkplane() && !SS.GW.showWorkplanes) return false;
if(IsNormal() && !SS.GW.showNormals) return false;
if(!SS.GW.showWorkplanes) {
if(IsWorkplane() && !h.isFromRequest()) {
// The group-associated workplanes are hidden outside their group.
if(g->h.v != SS.GW.activeGroup.v) return false;
if(g->h.v != SS.GW.activeGroup.v) {
// The group-associated workplanes are hidden outside
// their group.
return false;
}
}
}
if(forceHidden) return false;

View File

@ -107,7 +107,7 @@ void GraphicsWindow::Init(void) {
}
SS.GetGroup(activeGroup)->Activate();
showWorkplanes = true;
showWorkplanes = false;
showNormals = true;
showPoints = true;
showConstraints = true;
@ -258,12 +258,12 @@ void GraphicsWindow::MenuView(int id) {
break;
case MNU_UNITS_MM:
SS.GW.viewUnits = UNIT_MM;
SS.viewUnits = SolveSpace::UNIT_MM;
SS.GW.EnsureValidActives();
break;
case MNU_UNITS_INCHES:
SS.GW.viewUnits = UNIT_INCHES;
SS.viewUnits = SolveSpace::UNIT_INCHES;
SS.GW.EnsureValidActives();
break;
@ -272,21 +272,6 @@ void GraphicsWindow::MenuView(int id) {
InvalidateGraphics();
}
char *GraphicsWindow::ToString(double v) {
static int WhichBuf;
static char Bufs[8][128];
WhichBuf++;
if(WhichBuf >= 8 || WhichBuf < 0) WhichBuf = 0;
char *s = Bufs[WhichBuf];
sprintf(s, "%.3f", v);
return s;
}
double GraphicsWindow::FromString(char *s) {
return atof(s);
}
void GraphicsWindow::EnsureValidActives(void) {
bool change = false;
// The active group must exist, and not be the references.
@ -337,15 +322,15 @@ void GraphicsWindow::EnsureValidActives(void) {
SS.UndoEnableMenus();
switch(viewUnits) {
case UNIT_MM:
case UNIT_INCHES:
switch(SS.viewUnits) {
case SolveSpace::UNIT_MM:
case SolveSpace::UNIT_INCHES:
break;
default:
viewUnits = UNIT_MM;
SS.viewUnits = SolveSpace::UNIT_MM;
}
CheckMenuById(MNU_UNITS_MM, viewUnits == UNIT_MM);
CheckMenuById(MNU_UNITS_INCHES, viewUnits == UNIT_INCHES);
CheckMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpace::UNIT_MM);
CheckMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpace::UNIT_INCHES);
ShowTextWindow(SS.GW.showTextWindow);
CheckMenuById(MNU_SHOW_TEXT_WND, SS.GW.showTextWindow);

View File

@ -239,12 +239,6 @@ public:
static const int NORMAL_IN_3D = 3000;
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
// u = (sin theta)*uw - (cos theta)*vw
// v = nw
static const int NORMAL_IN_PLANE = 3002;
static const int NORMAL_N_COPY = 3010;
static const int NORMAL_N_ROT = 3011;
static const int NORMAL_N_ROT_AA = 3012;

View File

@ -25,6 +25,8 @@ void SolveSpace::Init(char *cmdLine) {
lightDir[1].z = ((int)CnfThawDWORD( 0, "LightDir_1_Forward" ))/1000.0;
// Mesh tolerance
meshTol = ((int)CnfThawDWORD(1000, "MeshTolerance"))/1000.0;
// View units
viewUnits = (Unit)CnfThawDWORD((DWORD)UNIT_MM, "ViewUnits");
// Recent files menus
for(i = 0; i < MAX_RECENT; i++) {
char name[100];
@ -73,7 +75,8 @@ void SolveSpace::Exit(void) {
CnfFreezeDWORD((int)(lightDir[1].z*1000), "LightDir_1_Forward");
// Mesh tolerance
CnfFreezeDWORD((int)(meshTol*1000), "MeshTolerance");
// Display/entry units
CnfFreezeDWORD((int)viewUnits, "ViewUnits");
ExitNow();
}
@ -88,6 +91,30 @@ int SolveSpace::CircleSides(double r) {
return min(s, 40);
}
char *SolveSpace::MmToString(double v) {
static int WhichBuf;
static char Bufs[8][128];
WhichBuf++;
if(WhichBuf >= 8 || WhichBuf < 0) WhichBuf = 0;
char *s = Bufs[WhichBuf];
if(viewUnits == UNIT_INCHES) {
sprintf(s, "%.3f", v/25.4);
} else {
sprintf(s, "%.2f", v);
}
return s;
}
double SolveSpace::ExprToMm(Expr *e) {
if(viewUnits == UNIT_INCHES) {
return (e->Eval())*25.4;
} else {
return e->Eval();
}
}
void SolveSpace::AfterNewFile(void) {
ReloadAllImported();
GenerateAll(-1, -1);

View File

@ -253,12 +253,19 @@ public:
Vector lightDir[2];
double lightIntensity[2];
double meshTol;
int CircleSides(double r);
typedef enum {
UNIT_MM = 0,
UNIT_INCHES,
} Unit;
Unit viewUnits;
char *MmToString(double v);
double ExprToMm(Expr *e);
// The platform-dependent code calls this before entering the msg loop
void Init(char *cmdLine);
void Exit(void);
int CircleSides(double r);
// File load/save routines, including the additional files that get
// loaded when we have import groups.
FILE *fh;

View File

@ -239,7 +239,7 @@ void TextWindow::DescribeSelection(void) {
e = SS.GetEntity(gs.points == 1 ? gs.point[0] : gs.entity[0]);
#define COSTR(p) \
SS.GW.ToString((p).x), SS.GW.ToString((p).y), SS.GW.ToString((p).z)
SS.MmToString((p).x), SS.MmToString((p).y), SS.MmToString((p).z)
#define PT_AS_STR "(%Fi%s%E, %Fi%s%E, %Fi%s%E)"
#define PT_AS_NUM "(%Fi%3%E, %Fi%3%E, %Fi%3%E)"
switch(e->type) {
@ -286,7 +286,7 @@ void TextWindow::DescribeSelection(void) {
p = p1;
Printf(false, " " PT_AS_STR, COSTR(p));
Printf(true, " len = %Fi%s%E",
SS.GW.ToString((p1.Minus(p0).Magnitude())));
SS.MmToString((p1.Minus(p0).Magnitude())));
break;
}
case Entity::CUBIC:
@ -306,8 +306,8 @@ void TextWindow::DescribeSelection(void) {
p = SS.GetEntity(e->point[2])->PointGetNum();
Printf(false, " " PT_AS_STR, COSTR(p));
double r = e->CircleGetRadiusNum();
Printf(true, " diameter = %Fi%s", SS.GW.ToString(r*2));
Printf(false, " radius = %Fi%s", SS.GW.ToString(r));
Printf(true, " diameter = %Fi%s", SS.MmToString(r*2));
Printf(false, " radius = %Fi%s", SS.MmToString(r));
break;
}
case Entity::CIRCLE: {
@ -315,8 +315,8 @@ void TextWindow::DescribeSelection(void) {
p = SS.GetEntity(e->point[0])->PointGetNum();
Printf(true, " center = " PT_AS_STR, COSTR(p));
double r = e->CircleGetRadiusNum();
Printf(true, " diameter = %Fi%s", SS.GW.ToString(r*2));
Printf(false, " radius = %Fi%s", SS.GW.ToString(r));
Printf(true, " diameter = %Fi%s", SS.MmToString(r*2));
Printf(false, " radius = %Fi%s", SS.MmToString(r));
break;
}
case Entity::FACE_NORMAL_PT:
@ -350,7 +350,7 @@ void TextWindow::DescribeSelection(void) {
Vector p1 = SS.GetEntity(gs.point[1])->PointGetNum();
Printf(false, " " PT_AS_STR, COSTR(p1));
double d = (p1.Minus(p0)).Magnitude();
Printf(true, " d = %Fi%s", SS.GW.ToString(d));
Printf(true, " d = %Fi%s", SS.MmToString(d));
} else if(gs.n == 2 && gs.faces == 1 && gs.points == 1) {
Printf(false, "%FtA POINT AND A PLANE FACE");
Vector pt = SS.GetEntity(gs.point[0])->PointGetNum();
@ -360,7 +360,7 @@ void TextWindow::DescribeSelection(void) {
Vector pl = SS.GetEntity(gs.face[0])->FaceGetPointNum();
Printf(false, " plane thru = " PT_AS_STR, COSTR(pl));
double dd = n.Dot(pl) - n.Dot(pt);
Printf(true, " distance = %Fi%s", SS.GW.ToString(dd));
Printf(true, " distance = %Fi%s", SS.MmToString(dd));
} else if(gs.n == 3 && gs.points == 2 && gs.vectors == 1) {
Printf(false, "%FtTWO POINTS AND A VECTOR");
Vector p0 = SS.GetEntity(gs.point[0])->PointGetNum();
@ -371,7 +371,7 @@ void TextWindow::DescribeSelection(void) {
v = v.WithMagnitude(1);
Printf(true, " vector = " PT_AS_NUM, CO(v));
double d = (p1.Minus(p0)).Dot(v);
Printf(true, " proj_d = %Fi%s", SS.GW.ToString(d));
Printf(true, " proj_d = %Fi%s", SS.MmToString(d));
} else if(gs.n == 2 && gs.faces == 2) {
Printf(false, "%FtTWO PLANE FACES");
@ -393,7 +393,7 @@ void TextWindow::DescribeSelection(void) {
if(fabs(theta) < 0.01) {
double d = (p1.Minus(p0)).Dot(n0);
Printf(true, " distance = %Fi%s", SS.GW.ToString(d));
Printf(true, " distance = %Fi%s", SS.MmToString(d));
}
} else {
Printf(true, "%FtSELECTED:%E %d item%s", gs.n, gs.n == 1 ? "" : "s");

8
ui.h
View File

@ -222,14 +222,6 @@ public:
void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin);
void ZoomToFit(void);
typedef enum {
UNIT_MM = 0,
UNIT_INCHES,
} Unit;
Unit viewUnits;
char *ToString(double v);
double FromString(char *str);
hGroup activeGroup;
void EnsureValidActives(void);
bool LockedInWorkplane(void);