Add a screen to edit the view parameters; scale, translation,

rotation. Also clean up the handling of units, by putting the
conversion factors in only one place, and clean up the
expression-parsing but removing all the copies of the same error
message.

[git-p4: depot-paths = "//depot/solvespace/": change = 2093]
solver
Jonathan Westhues 2010-01-03 16:35:28 -08:00
parent a4a1d3b619
commit ba8ac7dcd3
15 changed files with 232 additions and 85 deletions

View File

@ -19,6 +19,7 @@ SSOBJS = $(OBJDIR)\solvespace.obj \
$(OBJDIR)\graphicswin.obj \ $(OBJDIR)\graphicswin.obj \
$(OBJDIR)\modify.obj \ $(OBJDIR)\modify.obj \
$(OBJDIR)\clipboard.obj \ $(OBJDIR)\clipboard.obj \
$(OBJDIR)\view.obj \
$(OBJDIR)\util.obj \ $(OBJDIR)\util.obj \
$(OBJDIR)\style.obj \ $(OBJDIR)\style.obj \
$(OBJDIR)\entity.obj \ $(OBJDIR)\entity.obj \

View File

@ -317,7 +317,7 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) {
break; break;
} }
case EDIT_EXPORT_SCALE: { case EDIT_EXPORT_SCALE: {
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double ev = e->Eval(); double ev = e->Eval();
if(fabs(ev) < 0.001 || isnan(ev)) { if(fabs(ev) < 0.001 || isnan(ev)) {
@ -325,13 +325,11 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) {
} else { } else {
SS.exportScale = (float)ev; SS.exportScale = (float)ev;
} }
} else {
Error("Not a valid number or expression: '%s'", s);
} }
break; break;
} }
case EDIT_EXPORT_OFFSET: { case EDIT_EXPORT_OFFSET: {
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double ev = SS.ExprToMm(e); double ev = SS.ExprToMm(e);
if(isnan(ev) || ev < 0) { if(isnan(ev) || ev < 0) {
@ -339,15 +337,12 @@ bool TextWindow::EditControlDoneForConfiguration(char *s) {
} else { } else {
SS.exportOffset = (float)ev; SS.exportOffset = (float)ev;
} }
} else {
Error("Not a valid number or expression: '%s'", s);
} }
break; break;
} }
case EDIT_CANVAS_SIZE: { case EDIT_CANVAS_SIZE: {
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(!e) { if(!e) {
Error("Not a valid number or expression: '%s'", s);
break; break;
} }
float d = (float)SS.ExprToMm(e); float d = (float)SS.ExprToMm(e);

View File

@ -429,7 +429,16 @@ Vector GraphicsWindow::UnProjectPoint(Point2d p) {
} }
void GraphicsWindow::NormalizeProjectionVectors(void) { void GraphicsWindow::NormalizeProjectionVectors(void) {
if(projRight.Magnitude() < LENGTH_EPS) {
projRight = Vector::From(1, 0, 0);
}
Vector norm = projRight.Cross(projUp); Vector norm = projRight.Cross(projUp);
// If projRight and projUp somehow ended up parallel, then pick an
// arbitrary projUp normal to projRight.
if(norm.Magnitude() < LENGTH_EPS) {
norm = projRight.Normal(0);
}
projUp = norm.Cross(projRight); projUp = norm.Cross(projRight);
projUp = projUp.WithMagnitude(1); projUp = projUp.WithMagnitude(1);
@ -762,12 +771,12 @@ nogrid:;
glEnd(); glEnd();
} }
if(pending.drawLine) { if(SS.extraLine.draw) {
glLineWidth(1); glLineWidth(1);
glxLockColorTo(Style::Color(Style::DATUM)); glxLockColorTo(Style::Color(Style::DATUM));
glBegin(GL_LINES); glBegin(GL_LINES);
glxVertex3v(pending.lnA); glxVertex3v(SS.extraLine.ptA);
glxVertex3v(pending.lnB); glxVertex3v(SS.extraLine.ptB);
glEnd(); glEnd();
} }

View File

@ -763,7 +763,7 @@ void Expr::Lex(char *in) {
} }
} }
Expr *Expr::From(char *in) { Expr *Expr::From(char *in, bool popUpError) {
UnparsedCnt = 0; UnparsedCnt = 0;
UnparsedP = 0; UnparsedP = 0;
OperandsP = 0; OperandsP = 0;
@ -776,6 +776,9 @@ Expr *Expr::From(char *in) {
r = PopOperand(); r = PopOperand();
} catch (char *e) { } catch (char *e) {
dbp("exception: parse/lex error: %s", e); dbp("exception: parse/lex error: %s", e);
if(popUpError) {
Error("Not a valid number or expression: '%s'", in);
}
return NULL; return NULL;
} }
return r; return r;

2
expr.h
View File

@ -105,7 +105,7 @@ public:
Expr *DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry, Expr *DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
IdList<Param,hParam> *thenTry); IdList<Param,hParam> *thenTry);
static Expr *From(char *in); static Expr *From(char *in, bool popUpError);
static void Lex(char *in); static void Lex(char *in);
static Expr *Next(void); static Expr *Next(void);
static void Consume(void); static void Consume(void);

View File

@ -342,6 +342,7 @@ void GraphicsWindow::MenuView(int id) {
case MNU_ZOOM_TO_FIT: case MNU_ZOOM_TO_FIT:
SS.GW.ZoomToFit(false); SS.GW.ZoomToFit(false);
SS.later.showTW = true;
break; break;
case MNU_SHOW_GRID: case MNU_SHOW_GRID:
@ -521,6 +522,7 @@ void GraphicsWindow::EnsureValidActives(void) {
break; break;
default: default:
SS.viewUnits = SolveSpace::UNIT_MM; SS.viewUnits = SolveSpace::UNIT_MM;
break;
} }
CheckMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpace::UNIT_MM); CheckMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpace::UNIT_MM);
CheckMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpace::UNIT_INCHES); CheckMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpace::UNIT_INCHES);

View File

@ -79,7 +79,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
if(GraphicsEditControlIsVisible()) return; if(GraphicsEditControlIsVisible()) return;
if(context.active) return; if(context.active) return;
pending.drawLine = false; SS.extraLine.draw = false;
if(!orig.mouseDown) { if(!orig.mouseDown) {
// If someone drags the mouse into our window with the left button // If someone drags the mouse into our window with the left button
@ -133,9 +133,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
} else if(ctrlDown) { } else if(ctrlDown) {
double theta = atan2(orig.mouse.y, orig.mouse.x); double theta = atan2(orig.mouse.y, orig.mouse.x);
theta -= atan2(y, x); theta -= atan2(y, x);
pending.drawLine = true; SS.extraLine.draw = true;
pending.lnA = UnProjectPoint(Point2d::From(0, 0)); SS.extraLine.ptA = UnProjectPoint(Point2d::From(0, 0));
pending.lnB = UnProjectPoint(mp); SS.extraLine.ptB = UnProjectPoint(mp);
Vector normal = orig.projRight.Cross(orig.projUp); Vector normal = orig.projRight.Cross(orig.projUp);
projRight = orig.projRight.RotatedAbout(normal, theta); projRight = orig.projRight.RotatedAbout(normal, theta);
@ -154,7 +154,13 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
orig.mouse.x = x; orig.mouse.x = x;
orig.mouse.y = y; orig.mouse.y = y;
if(SS.TW.shown.screen == TextWindow::SCREEN_EDIT_VIEW) {
if(havePainted) {
SS.later.showTW = true;
}
}
InvalidateGraphics(); InvalidateGraphics();
havePainted = false;
return; return;
} }
@ -246,9 +252,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
// no sense solving a frame and not displaying it. // no sense solving a frame and not displaying it.
if(!havePainted) { if(!havePainted) {
if(pending.operation == DRAGGING_POINTS && ctrlDown) { if(pending.operation == DRAGGING_POINTS && ctrlDown) {
pending.lnA = UnProjectPoint(orig.mouseOnButtonDown); SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
pending.lnB = UnProjectPoint(mp); SS.extraLine.ptB = UnProjectPoint(mp);
pending.drawLine = true; SS.extraLine.draw = true;
} }
return; return;
} }
@ -293,9 +299,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
Vector gn = projRight.Cross(projUp); Vector gn = projRight.Cross(projUp);
qt = Quaternion::From(gn, -theta); qt = Quaternion::From(gn, -theta);
pending.drawLine = true; SS.extraLine.draw = true;
pending.lnA = UnProjectPoint(orig.mouseOnButtonDown); SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
pending.lnB = UnProjectPoint(mp); SS.extraLine.ptB = UnProjectPoint(mp);
} else { } else {
double dx = -(x - orig.mouse.x); double dx = -(x - orig.mouse.x);
double dy = -(y - orig.mouse.y); double dy = -(y - orig.mouse.y);
@ -312,9 +318,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
if(e->type != Entity::POINT_N_ROT_TRANS) { if(e->type != Entity::POINT_N_ROT_TRANS) {
if(ctrlDown) { if(ctrlDown) {
Vector p = e->PointGetNum(); Vector p = e->PointGetNum();
p = p.Minus(pending.lnA); p = p.Minus(SS.extraLine.ptA);
p = qt.Rotate(p); p = qt.Rotate(p);
p = p.Plus(pending.lnA); p = p.Plus(SS.extraLine.ptA);
e->PointForceTo(p); e->PointForceTo(p);
SS.MarkGroupDirtyByEntity(e->h); SS.MarkGroupDirtyByEntity(e->h);
} }
@ -478,7 +484,7 @@ void GraphicsWindow::ContextMenuListStyles(void) {
} }
void GraphicsWindow::MouseRightUp(double x, double y) { void GraphicsWindow::MouseRightUp(double x, double y) {
pending.drawLine = false; SS.extraLine.draw = false;
InvalidateGraphics(); InvalidateGraphics();
// Don't show a context menu if the user is right-clicking the toolbar, // Don't show a context menu if the user is right-clicking the toolbar,
@ -1134,7 +1140,7 @@ void GraphicsWindow::EditControlDone(char *s) {
return; return;
} }
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(e) { if(e) {
SS.UndoRemember(); SS.UndoRemember();
@ -1167,8 +1173,6 @@ void GraphicsWindow::EditControlDone(char *s) {
} }
SS.MarkGroupDirty(c->group); SS.MarkGroupDirty(c->group);
SS.GenerateAll(); SS.GenerateAll();
} else {
Error("Not a valid number or expression: '%s'", s);
} }
} }
@ -1201,6 +1205,12 @@ void GraphicsWindow::MouseScroll(double x, double y, int delta) {
offset = offset.Plus(projRight.ScaledBy(rightf - righti)); offset = offset.Plus(projRight.ScaledBy(rightf - righti));
offset = offset.Plus(projUp.ScaledBy(upf - upi)); offset = offset.Plus(projUp.ScaledBy(upf - upi));
if(SS.TW.shown.screen == TextWindow::SCREEN_EDIT_VIEW) {
if(havePainted) {
SS.later.showTW = true;
}
}
havePainted = false;
InvalidateGraphics(); InvalidateGraphics();
} }

View File

@ -199,6 +199,20 @@ void SolveSpace::DoLater(void) {
ZERO(&later); ZERO(&later);
} }
double SolveSpace::MmPerUnit(void) {
if(viewUnits == UNIT_INCHES) {
return 25.4;
} else {
return 1.0;
}
}
char *SolveSpace::UnitName(void) {
if(viewUnits == UNIT_INCHES) {
return "inch";
} else {
return "mm";
}
}
char *SolveSpace::MmToString(double v) { char *SolveSpace::MmToString(double v) {
static int WhichBuf; static int WhichBuf;
static char Bufs[8][128]; static char Bufs[8][128];
@ -215,18 +229,10 @@ char *SolveSpace::MmToString(double v) {
return s; return s;
} }
double SolveSpace::ExprToMm(Expr *e) { double SolveSpace::ExprToMm(Expr *e) {
if(viewUnits == UNIT_INCHES) { return (e->Eval()) * MmPerUnit();
return (e->Eval())*25.4;
} else {
return e->Eval();
}
} }
double SolveSpace::StringToMm(char *str) { double SolveSpace::StringToMm(char *str) {
if(viewUnits == UNIT_INCHES) { return atof(str) * MmPerUnit();
return atof(str)*25.4;
} else {
return atof(str);
}
} }
double SolveSpace::ChordTolMm(void) { double SolveSpace::ChordTolMm(void) {
return SS.chordTol / SS.GW.scale; return SS.chordTol / SS.GW.scale;

View File

@ -609,6 +609,8 @@ public:
char *MmToString(double v); char *MmToString(double v);
double ExprToMm(Expr *e); double ExprToMm(Expr *e);
double StringToMm(char *s); double StringToMm(char *s);
char *UnitName(void);
double MmPerUnit(void);
double ChordTolMm(void); double ChordTolMm(void);
bool forceParallelProj; bool forceParallelProj;
double CameraTangent(void); double CameraTangent(void);
@ -677,6 +679,11 @@ public:
hEntity point; hEntity point;
} traced; } traced;
SEdgeList nakedEdges; SEdgeList nakedEdges;
struct {
bool draw;
Vector ptA;
Vector ptB;
} extraLine;
struct { struct {
BYTE *fromFile; BYTE *fromFile;
int w, h; int w, h;

View File

@ -404,9 +404,7 @@ err:
void TextWindow::ScreenChangeBackgroundImageScale(int link, DWORD v) { void TextWindow::ScreenChangeBackgroundImageScale(int link, DWORD v) {
char str[300]; char str[300];
sprintf(str, "%.3f", sprintf(str, "%.3f", SS.bgImage.scale * SS.MmPerUnit());
(SS.viewUnits == SolveSpace::UNIT_MM) ? SS.bgImage.scale :
SS.bgImage.scale * 25.4);
SS.TW.edit.meaning = EDIT_BACKGROUND_IMG_SCALE; SS.TW.edit.meaning = EDIT_BACKGROUND_IMG_SCALE;
ShowTextEditControl(v, 10, str); ShowTextEditControl(v, 10, str);
} }
@ -443,15 +441,12 @@ void TextWindow::ShowListOfStyles(void) {
if(SS.bgImage.fromFile) { if(SS.bgImage.fromFile) {
Printf(false, "%Ba %Ftwidth:%E %dpx %Ftheight:%E %dpx", Printf(false, "%Ba %Ftwidth:%E %dpx %Ftheight:%E %dpx",
SS.bgImage.w, SS.bgImage.h); SS.bgImage.w, SS.bgImage.h);
if(SS.viewUnits == SolveSpace::UNIT_MM) {
Printf(false, " %Ftscale:%E %# px/mm %Fl%Ll%f%D[change]%E", Printf(false, " %Ftscale:%E %# px/%s %Fl%Ll%f%D[change]%E",
SS.bgImage.scale, SS.bgImage.scale*SS.MmPerUnit(),
SS.UnitName(),
&ScreenChangeBackgroundImageScale, top[rows-1] + 2); &ScreenChangeBackgroundImageScale, top[rows-1] + 2);
} else {
Printf(false, " %Ftscale:%E %# px/inch %Fl%Ll%f%D[change]%E",
SS.bgImage.scale*25.4,
&ScreenChangeBackgroundImageScale, top[rows-1] + 2);
}
Printf(false, "%Ba %Fl%Lc%fclear background image%E", Printf(false, "%Ba %Fl%Lc%fclear background image%E",
&ScreenBackgroundImage); &ScreenBackgroundImage);
} else { } else {
@ -682,18 +677,14 @@ bool TextWindow::EditControlDoneForStyles(char *str) {
break; break;
case EDIT_BACKGROUND_IMG_SCALE: { case EDIT_BACKGROUND_IMG_SCALE: {
Expr *e = Expr::From(str); Expr *e = Expr::From(str, true);
if(e) { if(e) {
double ev = e->Eval(); double ev = e->Eval();
if(ev < 0.001 || isnan(ev)) { if(ev < 0.001 || isnan(ev)) {
Error("Scale must not be zero or negative!"); Error("Scale must not be zero or negative!");
} else { } else {
SS.bgImage.scale = SS.bgImage.scale = ev / SS.MmPerUnit();
(SS.viewUnits == SolveSpace::UNIT_MM) ? ev :
ev / 25.4;
} }
} else {
Error("Not a valid number or expression: '%s'", str);
} }
break; break;
} }
@ -722,8 +713,6 @@ void TextWindow::ShowStyleInfo(void) {
REDf(s->color), GREENf(s->color), BLUEf(s->color), REDf(s->color), GREENf(s->color), BLUEf(s->color),
s->h.v, ScreenChangeStyleColor); s->h.v, ScreenChangeStyleColor);
char *unit = (SS.viewUnits == SolveSpace::UNIT_INCHES) ? "inches" : "mm";
// The line width, and its units // The line width, and its units
if(s->widthAs == Style::UNITS_AS_PIXELS) { if(s->widthAs == Style::UNITS_AS_PIXELS) {
Printf(true, "%FtLINE WIDTH %E%@ %D%f%Lp%Fl[change]%E", Printf(true, "%FtLINE WIDTH %E%@ %D%f%Lp%Fl[change]%E",
@ -747,8 +736,8 @@ void TextWindow::ShowStyleInfo(void) {
( widthpx ? "" : "pixels"), ( widthpx ? "" : "pixels"),
( widthpx ? "pixels" : ""), ( widthpx ? "pixels" : ""),
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
(!widthpx ? "" : unit), (!widthpx ? "" : SS.UnitName()),
(!widthpx ? unit : "")); (!widthpx ? SS.UnitName() : ""));
} }
if(s->h.v >= Style::FIRST_CUSTOM) { if(s->h.v >= Style::FIRST_CUSTOM) {
@ -793,8 +782,8 @@ void TextWindow::ShowStyleInfo(void) {
( textHeightpx ? "" : "pixels"), ( textHeightpx ? "" : "pixels"),
( textHeightpx ? "pixels" : ""), ( textHeightpx ? "pixels" : ""),
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
(!textHeightpx ? "" : unit), (!textHeightpx ? "" : SS.UnitName()),
(!textHeightpx ? unit : "")); (!textHeightpx ? SS.UnitName() : ""));
} }
if(s->h.v >= Style::FIRST_CUSTOM) { if(s->h.v >= Style::FIRST_CUSTOM) {

View File

@ -100,6 +100,9 @@ void TextWindow::ScreenHowGroupSolved(int link, DWORD v) {
void TextWindow::ScreenShowConfiguration(int link, DWORD v) { void TextWindow::ScreenShowConfiguration(int link, DWORD v) {
SS.TW.GoToScreen(SCREEN_CONFIGURATION); SS.TW.GoToScreen(SCREEN_CONFIGURATION);
} }
void TextWindow::ScreenShowEditView(int link, DWORD v) {
SS.TW.GoToScreen(SCREEN_EDIT_VIEW);
}
void TextWindow::ScreenGoToWebsite(int link, DWORD v) { void TextWindow::ScreenGoToWebsite(int link, DWORD v) {
OpenWebsite("http://solvespace.com/txtlink"); OpenWebsite("http://solvespace.com/txtlink");
} }
@ -143,8 +146,11 @@ void TextWindow::ShowListOfGroups(void) {
Printf(true, " %Fl%Ls%fshow all%E / %Fl%Lh%fhide all%E", Printf(true, " %Fl%Ls%fshow all%E / %Fl%Lh%fhide all%E",
&(TextWindow::ScreenShowGroupsSpecial), &(TextWindow::ScreenShowGroupsSpecial),
&(TextWindow::ScreenShowGroupsSpecial)); &(TextWindow::ScreenShowGroupsSpecial));
Printf(true, " %Fl%Ls%fline styles%E / %Fl%Ls%fconfiguration%E", Printf(true, " %Fl%Ls%fline styles%E /"
" %Fl%Ls%fview%E /"
" %Fl%Ls%fconfiguration%E",
&(TextWindow::ScreenShowListOfStyles), &(TextWindow::ScreenShowListOfStyles),
&(TextWindow::ScreenShowEditView),
&(TextWindow::ScreenShowConfiguration)); &(TextWindow::ScreenShowConfiguration));
// Show license info // Show license info
@ -674,10 +680,11 @@ void TextWindow::ShowStepDimension(void) {
void TextWindow::ShowMeshVolume(void) { void TextWindow::ShowMeshVolume(void) {
Printf(true, "%FtMESH VOLUME"); Printf(true, "%FtMESH VOLUME");
if(SS.viewUnits == SolveSpace::UNIT_INCHES) { Printf(true, " %3 %s^3",
Printf(true, " %3 in^3", shown.volume/(25.4*25.4*25.4)); shown.volume / pow(SS.MmPerUnit(), 3),
} else { SS.UnitName());
Printf(true, " %2 mm^3", shown.volume);
if(SS.viewUnits == SolveSpace::UNIT_MM) {
Printf(false, " %2 mL", shown.volume/(10*10*10)); Printf(false, " %2 mL", shown.volume/(10*10*10));
} }
@ -688,9 +695,11 @@ void TextWindow::ShowMeshVolume(void) {
// The edit control is visible, and the user just pressed enter. // The edit control is visible, and the user just pressed enter.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void TextWindow::EditControlDone(char *s) { void TextWindow::EditControlDone(char *s) {
edit.showAgain = false;
switch(edit.meaning) { switch(edit.meaning) {
case EDIT_TIMES_REPEATED: { case EDIT_TIMES_REPEATED: {
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(e) { if(e) {
SS.UndoRemember(); SS.UndoRemember();
@ -721,8 +730,6 @@ void TextWindow::EditControlDone(char *s) {
SS.MarkGroupDirty(g->h); SS.MarkGroupDirty(g->h);
SS.later.generateAll = true; SS.later.generateAll = true;
} else {
Error("Not a valid number or expression: '%s'", s);
} }
break; break;
} }
@ -738,7 +745,7 @@ void TextWindow::EditControlDone(char *s) {
break; break;
} }
case EDIT_GROUP_SCALE: { case EDIT_GROUP_SCALE: {
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double ev = e->Eval(); double ev = e->Eval();
if(fabs(ev) < 1e-6) { if(fabs(ev) < 1e-6) {
@ -749,8 +756,6 @@ void TextWindow::EditControlDone(char *s) {
SS.MarkGroupDirty(g->h); SS.MarkGroupDirty(g->h);
SS.later.generateAll = true; SS.later.generateAll = true;
} }
} else {
Error("Not a valid number or expression: '%s'", s);
} }
break; break;
} }
@ -759,9 +764,8 @@ void TextWindow::EditControlDone(char *s) {
case EDIT_HELIX_DRADIUS: { case EDIT_HELIX_DRADIUS: {
SS.UndoRemember(); SS.UndoRemember();
Group *g = SK.GetGroup(edit.group); Group *g = SK.GetGroup(edit.group);
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(!e) { if(!e) {
Error("Not a valid number or expression: '%s'", s);
break; break;
} }
if(edit.meaning == EDIT_HELIX_TURNS) { if(edit.meaning == EDIT_HELIX_TURNS) {
@ -786,9 +790,8 @@ void TextWindow::EditControlDone(char *s) {
break; break;
} }
case EDIT_STEP_DIM_FINISH: { case EDIT_STEP_DIM_FINISH: {
Expr *e = Expr::From(s); Expr *e = Expr::From(s, true);
if(!e) { if(!e) {
Error("Not a valid number or expression: '%s'", s);
break; break;
} }
if(shown.dimIsDistance) { if(shown.dimIsDistance) {
@ -807,6 +810,7 @@ void TextWindow::EditControlDone(char *s) {
if(EditControlDoneForStyles(s)) cnt++; if(EditControlDoneForStyles(s)) cnt++;
if(EditControlDoneForConfiguration(s)) cnt++; if(EditControlDoneForConfiguration(s)) cnt++;
if(EditControlDoneForPaste(s)) cnt++; if(EditControlDoneForPaste(s)) cnt++;
if(EditControlDoneForView(s)) cnt++;
if(cnt > 1) { if(cnt > 1) {
// The identifiers were somehow assigned not uniquely? // The identifiers were somehow assigned not uniquely?
oops(); oops();
@ -816,7 +820,10 @@ void TextWindow::EditControlDone(char *s) {
} }
InvalidateGraphics(); InvalidateGraphics();
SS.later.showTW = true; SS.later.showTW = true;
if(!edit.showAgain) {
HideTextEditControl(); HideTextEditControl();
edit.meaning = EDIT_NOTHING; edit.meaning = EDIT_NOTHING;
} }
}

View File

@ -238,6 +238,7 @@ void TextWindow::Show(void) {
case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break; case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break;
case SCREEN_STYLE_INFO: ShowStyleInfo(); break; case SCREEN_STYLE_INFO: ShowStyleInfo(); break;
case SCREEN_PASTE_TRANSFORMED: ShowPasteTransformed(); break; case SCREEN_PASTE_TRANSFORMED: ShowPasteTransformed(); break;
case SCREEN_EDIT_VIEW: ShowEditView(); break;
} }
} }
Printf(false, ""); Printf(false, "");

16
ui.h
View File

@ -55,6 +55,7 @@ public:
static const int SCREEN_LIST_OF_STYLES = 6; static const int SCREEN_LIST_OF_STYLES = 6;
static const int SCREEN_STYLE_INFO = 7; static const int SCREEN_STYLE_INFO = 7;
static const int SCREEN_PASTE_TRANSFORMED = 8; static const int SCREEN_PASTE_TRANSFORMED = 8;
static const int SCREEN_EDIT_VIEW = 9;
typedef struct { typedef struct {
int screen; int screen;
@ -116,7 +117,13 @@ public:
static const int EDIT_PASTE_TIMES_REPEATED = 60; static const int EDIT_PASTE_TIMES_REPEATED = 60;
static const int EDIT_PASTE_ANGLE = 61; static const int EDIT_PASTE_ANGLE = 61;
static const int EDIT_PASTE_SCALE = 62; static const int EDIT_PASTE_SCALE = 62;
// For view
static const int EDIT_VIEW_SCALE = 70;
static const int EDIT_VIEW_ORIGIN = 71;
static const int EDIT_VIEW_PROJ_RIGHT = 72;
static const int EDIT_VIEW_PROJ_UP = 73;
struct { struct {
bool showAgain;
int meaning; int meaning;
int i; int i;
hGroup group; hGroup group;
@ -140,6 +147,7 @@ public:
void ShowStepDimension(void); void ShowStepDimension(void);
void ShowMeshVolume(void); void ShowMeshVolume(void);
void ShowPasteTransformed(void); void ShowPasteTransformed(void);
void ShowEditView(void);
// Special screen, based on selection // Special screen, based on selection
void DescribeSelection(void); void DescribeSelection(void);
@ -179,6 +187,7 @@ public:
static void ScreenBackgroundImage(int link, DWORD v); static void ScreenBackgroundImage(int link, DWORD v);
static void ScreenShowConfiguration(int link, DWORD v); static void ScreenShowConfiguration(int link, DWORD v);
static void ScreenShowEditView(int link, DWORD v);
static void ScreenGoToWebsite(int link, DWORD v); static void ScreenGoToWebsite(int link, DWORD v);
static void ScreenChangeFixExportColors(int link, DWORD v); static void ScreenChangeFixExportColors(int link, DWORD v);
@ -217,10 +226,14 @@ public:
static void ScreenChangeBackgroundColor(int link, DWORD v); static void ScreenChangeBackgroundColor(int link, DWORD v);
static void ScreenChangeBackgroundImageScale(int link, DWORD v); static void ScreenChangeBackgroundImageScale(int link, DWORD v);
static void ScreenChangePasteTransformed(int link, DWORD v); static void ScreenChangePasteTransformed(int link, DWORD v);
static void ScreenChangeViewScale(int link, DWORD v);
static void ScreenChangeViewOrigin(int link, DWORD v);
static void ScreenChangeViewProjection(int link, DWORD v);
bool EditControlDoneForStyles(char *s); bool EditControlDoneForStyles(char *s);
bool EditControlDoneForConfiguration(char *s); bool EditControlDoneForConfiguration(char *s);
bool EditControlDoneForPaste(char *s); bool EditControlDoneForPaste(char *s);
bool EditControlDoneForView(char *s);
void EditControlDone(char *s); void EditControlDone(char *s);
}; };
@ -413,9 +426,6 @@ public:
hEntity normal; hEntity normal;
hConstraint constraint; hConstraint constraint;
bool drawLine;
Vector lnA, lnB;
char *description; char *description;
} pending; } pending;
void ClearPending(void); void ClearPending(void);

109
view.cpp Normal file
View File

@ -0,0 +1,109 @@
#include "solvespace.h"
void TextWindow::ShowEditView(void) {
Printf(true, "%Ft3D VIEW PARAMETERS%E");
Printf(true, "%Bd %Ftoverall scale factor%E");
Printf(false, "%Ba %# px/%s %Fl%Ll%f[edit]%E",
SS.GW.scale * SS.MmPerUnit(),
SS.UnitName(),
&ScreenChangeViewScale);
Printf(false, "");
Printf(false, "%Bd %Ftorigin (maps to center of screen)%E");
Printf(false, "%Ba (%s, %s, %s) %Fl%Ll%f[edit]%E",
SS.MmToString(-SS.GW.offset.x),
SS.MmToString(-SS.GW.offset.y),
SS.MmToString(-SS.GW.offset.z),
&ScreenChangeViewOrigin);
Printf(false, "");
Vector n = (SS.GW.projRight).Cross(SS.GW.projUp);
Printf(false, "%Bd %Ftprojection onto screen%E");
Printf(false, "%Ba %Ftright%E (%3, %3, %3) %Fl%Ll%f[edit]%E",
CO(SS.GW.projRight),
&ScreenChangeViewProjection);
Printf(false, "%Ba %Ftup%E (%3, %3, %3)", CO(SS.GW.projUp));
Printf(false, "%Ba %Ftout%E (%3, %3, %3)", CO(n));
Printf(false, "");
Printf(false, "The perspective may be changed in the");
Printf(false, "configuration screen.");
}
void TextWindow::ScreenChangeViewScale(int link, DWORD v) {
char buf[1024];
sprintf(buf, "%.3f", SS.GW.scale * SS.MmPerUnit());
SS.TW.edit.meaning = EDIT_VIEW_SCALE;
ShowTextEditControl(12, 3, buf);
}
void TextWindow::ScreenChangeViewOrigin(int link, DWORD v) {
char buf[1024];
sprintf(buf, "%s, %s, %s",
SS.MmToString(-SS.GW.offset.x),
SS.MmToString(-SS.GW.offset.y),
SS.MmToString(-SS.GW.offset.z));
SS.TW.edit.meaning = EDIT_VIEW_ORIGIN;
ShowTextEditControl(18, 3, buf);
}
void TextWindow::ScreenChangeViewProjection(int link, DWORD v) {
char buf[1024];
sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projRight));
SS.TW.edit.meaning = EDIT_VIEW_PROJ_RIGHT;
ShowTextEditControl(24, 10, buf);
}
bool TextWindow::EditControlDoneForView(char *s) {
switch(edit.meaning) {
case EDIT_VIEW_SCALE: {
Expr *e = Expr::From(s, true);
if(e) {
SS.GW.scale = e->Eval() / SS.MmPerUnit();
}
break;
}
case EDIT_VIEW_ORIGIN: {
Vector pt;
if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) {
pt = pt.ScaledBy(SS.MmPerUnit());
SS.GW.offset = pt.ScaledBy(-1);
} else {
Error("Bad format: specify x, y, z");
}
break;
}
case EDIT_VIEW_PROJ_RIGHT:
case EDIT_VIEW_PROJ_UP: {
Vector pt;
if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) {
Error("Bad format: specify x, y, z");
break;
}
if(edit.meaning == EDIT_VIEW_PROJ_RIGHT) {
SS.GW.projRight = pt;
SS.GW.NormalizeProjectionVectors();
edit.meaning = EDIT_VIEW_PROJ_UP;
char buf[1024];
sprintf(buf, "%.3f, %.3f, %.3f", CO(SS.GW.projUp));
HideTextEditControl();
ShowTextEditControl(26, 10, buf);
edit.showAgain = true;
} else {
SS.GW.projUp = pt;
SS.GW.NormalizeProjectionVectors();
}
break;
}
default:
return false;
}
return true;
}

View File

@ -1,6 +1,4 @@
show and modify view parameters (translate, rotate, scale)
----- -----
associative entities from solid model, as a special group associative entities from solid model, as a special group
some kind of import some kind of import