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
parent
28e3f0abab
commit
d391c43bff
45
draw.cpp
45
draw.cpp
|
@ -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 {
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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(IsWorkplane() && !h.isFromRequest()) {
|
if(!SS.GW.showWorkplanes) {
|
||||||
// The group-associated workplanes are hidden outside their group.
|
if(IsWorkplane() && !h.isFromRequest()) {
|
||||||
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;
|
if(forceHidden) return false;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
6
sketch.h
6
sketch.h
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
11
solvespace.h
11
solvespace.h
|
@ -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;
|
||||||
|
|
20
textwin.cpp
20
textwin.cpp
|
@ -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
8
ui.h
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue