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(); Vector p3 = c->GetLabelPos();
Point2d p2 = ProjectPoint(p3); 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); ShowGraphicsEditControl((int)p2.x, (int)p2.y-4, s);
} }
} }
@ -575,8 +589,33 @@ void GraphicsWindow::EditControlDone(char *s) {
if(e) { if(e) {
SS.UndoRemember(); 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.MarkGroupDirty(c->group);
SS.GenerateAll(); SS.GenerateAll();
} else { } else {

View File

@ -51,7 +51,7 @@ char *Constraint::Label(void) {
strcpy(Ret, comment.str); strcpy(Ret, comment.str);
} else { } else {
// valA has units of distance // valA has units of distance
strcpy(Ret, SS.GW.ToString(valA)); strcpy(Ret, SS.MmToString(fabs(valA)));
} }
if(reference) { if(reference) {
strcat(Ret, " REF"); 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 // Don't check if points are hidden; this gets called only for
// selected or hovered points, and those should always be shown. // 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(IsNormal() && !SS.GW.showNormals) return false;
if(!SS.GW.showWorkplanes) {
if(IsWorkplane() && !h.isFromRequest()) { if(IsWorkplane() && !h.isFromRequest()) {
// The group-associated workplanes are hidden outside their group. if(g->h.v != SS.GW.activeGroup.v) {
if(g->h.v != SS.GW.activeGroup.v) return false; // The group-associated workplanes are hidden outside
// their group.
return false;
}
}
} }
if(forceHidden) return false; if(forceHidden) return false;

View File

@ -107,7 +107,7 @@ void GraphicsWindow::Init(void) {
} }
SS.GetGroup(activeGroup)->Activate(); SS.GetGroup(activeGroup)->Activate();
showWorkplanes = true; showWorkplanes = false;
showNormals = true; showNormals = true;
showPoints = true; showPoints = true;
showConstraints = true; showConstraints = true;
@ -258,12 +258,12 @@ void GraphicsWindow::MenuView(int id) {
break; break;
case MNU_UNITS_MM: case MNU_UNITS_MM:
SS.GW.viewUnits = UNIT_MM; SS.viewUnits = SolveSpace::UNIT_MM;
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
case MNU_UNITS_INCHES: case MNU_UNITS_INCHES:
SS.GW.viewUnits = UNIT_INCHES; SS.viewUnits = SolveSpace::UNIT_INCHES;
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
@ -272,21 +272,6 @@ void GraphicsWindow::MenuView(int id) {
InvalidateGraphics(); 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) { void GraphicsWindow::EnsureValidActives(void) {
bool change = false; bool change = false;
// The active group must exist, and not be the references. // The active group must exist, and not be the references.
@ -337,15 +322,15 @@ void GraphicsWindow::EnsureValidActives(void) {
SS.UndoEnableMenus(); SS.UndoEnableMenus();
switch(viewUnits) { switch(SS.viewUnits) {
case UNIT_MM: case SolveSpace::UNIT_MM:
case UNIT_INCHES: case SolveSpace::UNIT_INCHES:
break; break;
default: default:
viewUnits = UNIT_MM; SS.viewUnits = SolveSpace::UNIT_MM;
} }
CheckMenuById(MNU_UNITS_MM, viewUnits == UNIT_MM); CheckMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpace::UNIT_MM);
CheckMenuById(MNU_UNITS_INCHES, viewUnits == UNIT_INCHES); CheckMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpace::UNIT_INCHES);
ShowTextWindow(SS.GW.showTextWindow); ShowTextWindow(SS.GW.showTextWindow);
CheckMenuById(MNU_SHOW_TEXT_WND, 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_3D = 3000;
static const int NORMAL_IN_2D = 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
// 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_COPY = 3010;
static const int NORMAL_N_ROT = 3011; static const int NORMAL_N_ROT = 3011;
static const int NORMAL_N_ROT_AA = 3012; 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; lightDir[1].z = ((int)CnfThawDWORD( 0, "LightDir_1_Forward" ))/1000.0;
// Mesh tolerance // Mesh tolerance
meshTol = ((int)CnfThawDWORD(1000, "MeshTolerance"))/1000.0; meshTol = ((int)CnfThawDWORD(1000, "MeshTolerance"))/1000.0;
// View units
viewUnits = (Unit)CnfThawDWORD((DWORD)UNIT_MM, "ViewUnits");
// Recent files menus // Recent files menus
for(i = 0; i < MAX_RECENT; i++) { for(i = 0; i < MAX_RECENT; i++) {
char name[100]; char name[100];
@ -73,7 +75,8 @@ void SolveSpace::Exit(void) {
CnfFreezeDWORD((int)(lightDir[1].z*1000), "LightDir_1_Forward"); CnfFreezeDWORD((int)(lightDir[1].z*1000), "LightDir_1_Forward");
// Mesh tolerance // Mesh tolerance
CnfFreezeDWORD((int)(meshTol*1000), "MeshTolerance"); CnfFreezeDWORD((int)(meshTol*1000), "MeshTolerance");
// Display/entry units
CnfFreezeDWORD((int)viewUnits, "ViewUnits");
ExitNow(); ExitNow();
} }
@ -88,6 +91,30 @@ int SolveSpace::CircleSides(double r) {
return min(s, 40); 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) { void SolveSpace::AfterNewFile(void) {
ReloadAllImported(); ReloadAllImported();
GenerateAll(-1, -1); GenerateAll(-1, -1);

View File

@ -253,12 +253,19 @@ public:
Vector lightDir[2]; Vector lightDir[2];
double lightIntensity[2]; double lightIntensity[2];
double meshTol; 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 Init(char *cmdLine);
void Exit(void); void Exit(void);
int CircleSides(double r);
// File load/save routines, including the additional files that get // File load/save routines, including the additional files that get
// loaded when we have import groups. // loaded when we have import groups.
FILE *fh; FILE *fh;

View File

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