diff --git a/draw.cpp b/draw.cpp index 0a70b75b..fbb7a1b8 100644 --- a/draw.cpp +++ b/draw.cpp @@ -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 { diff --git a/drawconstraint.cpp b/drawconstraint.cpp index 5289d6b1..fef86217 100644 --- a/drawconstraint.cpp +++ b/drawconstraint.cpp @@ -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"); diff --git a/drawentity.cpp b/drawentity.cpp index c7659526..6e5d9854 100644 --- a/drawentity.cpp +++ b/drawentity.cpp @@ -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(IsWorkplane() && !h.isFromRequest()) { - // The group-associated workplanes are hidden outside their group. - if(g->h.v != SS.GW.activeGroup.v) return false; + if(!SS.GW.showWorkplanes) { + if(IsWorkplane() && !h.isFromRequest()) { + if(g->h.v != SS.GW.activeGroup.v) { + // The group-associated workplanes are hidden outside + // their group. + return false; + } + } } if(forceHidden) return false; diff --git a/graphicswin.cpp b/graphicswin.cpp index 29628666..bfe97ae3 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -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); diff --git a/sketch.h b/sketch.h index 3738912f..90402d8b 100644 --- a/sketch.h +++ b/sketch.h @@ -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; diff --git a/solvespace.cpp b/solvespace.cpp index 36d45d72..e8f5af36 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -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); diff --git a/solvespace.h b/solvespace.h index 8e4253a0..46fb9be3 100644 --- a/solvespace.h +++ b/solvespace.h @@ -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; diff --git a/textwin.cpp b/textwin.cpp index 67876ad0..17404396 100644 --- a/textwin.cpp +++ b/textwin.cpp @@ -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"); diff --git a/ui.h b/ui.h index 8c75ffed..7ebbb337 100644 --- a/ui.h +++ b/ui.h @@ -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);