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)\modify.obj \
$(OBJDIR)\clipboard.obj \
$(OBJDIR)\view.obj \
$(OBJDIR)\util.obj \
$(OBJDIR)\style.obj \
$(OBJDIR)\entity.obj \

View File

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

View File

@ -429,7 +429,16 @@ Vector GraphicsWindow::UnProjectPoint(Point2d p) {
}
void GraphicsWindow::NormalizeProjectionVectors(void) {
if(projRight.Magnitude() < LENGTH_EPS) {
projRight = Vector::From(1, 0, 0);
}
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 = projUp.WithMagnitude(1);
@ -762,12 +771,12 @@ nogrid:;
glEnd();
}
if(pending.drawLine) {
if(SS.extraLine.draw) {
glLineWidth(1);
glxLockColorTo(Style::Color(Style::DATUM));
glBegin(GL_LINES);
glxVertex3v(pending.lnA);
glxVertex3v(pending.lnB);
glxVertex3v(SS.extraLine.ptA);
glxVertex3v(SS.extraLine.ptB);
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;
UnparsedP = 0;
OperandsP = 0;
@ -776,6 +776,9 @@ Expr *Expr::From(char *in) {
r = PopOperand();
} catch (char *e) {
dbp("exception: parse/lex error: %s", e);
if(popUpError) {
Error("Not a valid number or expression: '%s'", in);
}
return NULL;
}
return r;

2
expr.h
View File

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

View File

@ -342,6 +342,7 @@ void GraphicsWindow::MenuView(int id) {
case MNU_ZOOM_TO_FIT:
SS.GW.ZoomToFit(false);
SS.later.showTW = true;
break;
case MNU_SHOW_GRID:
@ -521,6 +522,7 @@ void GraphicsWindow::EnsureValidActives(void) {
break;
default:
SS.viewUnits = SolveSpace::UNIT_MM;
break;
}
CheckMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpace::UNIT_MM);
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(context.active) return;
pending.drawLine = false;
SS.extraLine.draw = false;
if(!orig.mouseDown) {
// 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) {
double theta = atan2(orig.mouse.y, orig.mouse.x);
theta -= atan2(y, x);
pending.drawLine = true;
pending.lnA = UnProjectPoint(Point2d::From(0, 0));
pending.lnB = UnProjectPoint(mp);
SS.extraLine.draw = true;
SS.extraLine.ptA = UnProjectPoint(Point2d::From(0, 0));
SS.extraLine.ptB = UnProjectPoint(mp);
Vector normal = orig.projRight.Cross(orig.projUp);
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.y = y;
if(SS.TW.shown.screen == TextWindow::SCREEN_EDIT_VIEW) {
if(havePainted) {
SS.later.showTW = true;
}
}
InvalidateGraphics();
havePainted = false;
return;
}
@ -246,9 +252,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
// no sense solving a frame and not displaying it.
if(!havePainted) {
if(pending.operation == DRAGGING_POINTS && ctrlDown) {
pending.lnA = UnProjectPoint(orig.mouseOnButtonDown);
pending.lnB = UnProjectPoint(mp);
pending.drawLine = true;
SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
SS.extraLine.ptB = UnProjectPoint(mp);
SS.extraLine.draw = true;
}
return;
}
@ -293,9 +299,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
Vector gn = projRight.Cross(projUp);
qt = Quaternion::From(gn, -theta);
pending.drawLine = true;
pending.lnA = UnProjectPoint(orig.mouseOnButtonDown);
pending.lnB = UnProjectPoint(mp);
SS.extraLine.draw = true;
SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown);
SS.extraLine.ptB = UnProjectPoint(mp);
} else {
double dx = -(x - orig.mouse.x);
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(ctrlDown) {
Vector p = e->PointGetNum();
p = p.Minus(pending.lnA);
p = p.Minus(SS.extraLine.ptA);
p = qt.Rotate(p);
p = p.Plus(pending.lnA);
p = p.Plus(SS.extraLine.ptA);
e->PointForceTo(p);
SS.MarkGroupDirtyByEntity(e->h);
}
@ -478,7 +484,7 @@ void GraphicsWindow::ContextMenuListStyles(void) {
}
void GraphicsWindow::MouseRightUp(double x, double y) {
pending.drawLine = false;
SS.extraLine.draw = false;
InvalidateGraphics();
// Don't show a context menu if the user is right-clicking the toolbar,
@ -1134,7 +1140,7 @@ void GraphicsWindow::EditControlDone(char *s) {
return;
}
Expr *e = Expr::From(s);
Expr *e = Expr::From(s, true);
if(e) {
SS.UndoRemember();
@ -1167,8 +1173,6 @@ void GraphicsWindow::EditControlDone(char *s) {
}
SS.MarkGroupDirty(c->group);
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(projUp.ScaledBy(upf - upi));
if(SS.TW.shown.screen == TextWindow::SCREEN_EDIT_VIEW) {
if(havePainted) {
SS.later.showTW = true;
}
}
havePainted = false;
InvalidateGraphics();
}

View File

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

View File

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

View File

@ -404,9 +404,7 @@ err:
void TextWindow::ScreenChangeBackgroundImageScale(int link, DWORD v) {
char str[300];
sprintf(str, "%.3f",
(SS.viewUnits == SolveSpace::UNIT_MM) ? SS.bgImage.scale :
SS.bgImage.scale * 25.4);
sprintf(str, "%.3f", SS.bgImage.scale * SS.MmPerUnit());
SS.TW.edit.meaning = EDIT_BACKGROUND_IMG_SCALE;
ShowTextEditControl(v, 10, str);
}
@ -443,15 +441,12 @@ void TextWindow::ShowListOfStyles(void) {
if(SS.bgImage.fromFile) {
Printf(false, "%Ba %Ftwidth:%E %dpx %Ftheight:%E %dpx",
SS.bgImage.w, SS.bgImage.h);
if(SS.viewUnits == SolveSpace::UNIT_MM) {
Printf(false, " %Ftscale:%E %# px/mm %Fl%Ll%f%D[change]%E",
SS.bgImage.scale,
&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, " %Ftscale:%E %# px/%s %Fl%Ll%f%D[change]%E",
SS.bgImage.scale*SS.MmPerUnit(),
SS.UnitName(),
&ScreenChangeBackgroundImageScale, top[rows-1] + 2);
Printf(false, "%Ba %Fl%Lc%fclear background image%E",
&ScreenBackgroundImage);
} else {
@ -682,18 +677,14 @@ bool TextWindow::EditControlDoneForStyles(char *str) {
break;
case EDIT_BACKGROUND_IMG_SCALE: {
Expr *e = Expr::From(str);
Expr *e = Expr::From(str, true);
if(e) {
double ev = e->Eval();
if(ev < 0.001 || isnan(ev)) {
Error("Scale must not be zero or negative!");
} else {
SS.bgImage.scale =
(SS.viewUnits == SolveSpace::UNIT_MM) ? ev :
ev / 25.4;
SS.bgImage.scale = ev / SS.MmPerUnit();
}
} else {
Error("Not a valid number or expression: '%s'", str);
}
break;
}
@ -722,8 +713,6 @@ void TextWindow::ShowStyleInfo(void) {
REDf(s->color), GREENf(s->color), BLUEf(s->color),
s->h.v, ScreenChangeStyleColor);
char *unit = (SS.viewUnits == SolveSpace::UNIT_INCHES) ? "inches" : "mm";
// The line width, and its units
if(s->widthAs == Style::UNITS_AS_PIXELS) {
Printf(true, "%FtLINE WIDTH %E%@ %D%f%Lp%Fl[change]%E",
@ -747,8 +736,8 @@ void TextWindow::ShowStyleInfo(void) {
( widthpx ? "" : "pixels"),
( widthpx ? "pixels" : ""),
s->h.v, &ScreenChangeStyleYesNo,
(!widthpx ? "" : unit),
(!widthpx ? unit : ""));
(!widthpx ? "" : SS.UnitName()),
(!widthpx ? SS.UnitName() : ""));
}
if(s->h.v >= Style::FIRST_CUSTOM) {
@ -793,8 +782,8 @@ void TextWindow::ShowStyleInfo(void) {
( textHeightpx ? "" : "pixels"),
( textHeightpx ? "pixels" : ""),
s->h.v, &ScreenChangeStyleYesNo,
(!textHeightpx ? "" : unit),
(!textHeightpx ? unit : ""));
(!textHeightpx ? "" : SS.UnitName()),
(!textHeightpx ? SS.UnitName() : ""));
}
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) {
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) {
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",
&(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::ScreenShowEditView),
&(TextWindow::ScreenShowConfiguration));
// Show license info
@ -674,10 +680,11 @@ void TextWindow::ShowStepDimension(void) {
void TextWindow::ShowMeshVolume(void) {
Printf(true, "%FtMESH VOLUME");
if(SS.viewUnits == SolveSpace::UNIT_INCHES) {
Printf(true, " %3 in^3", shown.volume/(25.4*25.4*25.4));
} else {
Printf(true, " %2 mm^3", shown.volume);
Printf(true, " %3 %s^3",
shown.volume / pow(SS.MmPerUnit(), 3),
SS.UnitName());
if(SS.viewUnits == SolveSpace::UNIT_MM) {
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.
//-----------------------------------------------------------------------------
void TextWindow::EditControlDone(char *s) {
edit.showAgain = false;
switch(edit.meaning) {
case EDIT_TIMES_REPEATED: {
Expr *e = Expr::From(s);
Expr *e = Expr::From(s, true);
if(e) {
SS.UndoRemember();
@ -721,8 +730,6 @@ void TextWindow::EditControlDone(char *s) {
SS.MarkGroupDirty(g->h);
SS.later.generateAll = true;
} else {
Error("Not a valid number or expression: '%s'", s);
}
break;
}
@ -738,7 +745,7 @@ void TextWindow::EditControlDone(char *s) {
break;
}
case EDIT_GROUP_SCALE: {
Expr *e = Expr::From(s);
Expr *e = Expr::From(s, true);
if(e) {
double ev = e->Eval();
if(fabs(ev) < 1e-6) {
@ -749,8 +756,6 @@ void TextWindow::EditControlDone(char *s) {
SS.MarkGroupDirty(g->h);
SS.later.generateAll = true;
}
} else {
Error("Not a valid number or expression: '%s'", s);
}
break;
}
@ -759,9 +764,8 @@ void TextWindow::EditControlDone(char *s) {
case EDIT_HELIX_DRADIUS: {
SS.UndoRemember();
Group *g = SK.GetGroup(edit.group);
Expr *e = Expr::From(s);
Expr *e = Expr::From(s, true);
if(!e) {
Error("Not a valid number or expression: '%s'", s);
break;
}
if(edit.meaning == EDIT_HELIX_TURNS) {
@ -786,9 +790,8 @@ void TextWindow::EditControlDone(char *s) {
break;
}
case EDIT_STEP_DIM_FINISH: {
Expr *e = Expr::From(s);
Expr *e = Expr::From(s, true);
if(!e) {
Error("Not a valid number or expression: '%s'", s);
break;
}
if(shown.dimIsDistance) {
@ -807,6 +810,7 @@ void TextWindow::EditControlDone(char *s) {
if(EditControlDoneForStyles(s)) cnt++;
if(EditControlDoneForConfiguration(s)) cnt++;
if(EditControlDoneForPaste(s)) cnt++;
if(EditControlDoneForView(s)) cnt++;
if(cnt > 1) {
// The identifiers were somehow assigned not uniquely?
oops();
@ -816,7 +820,10 @@ void TextWindow::EditControlDone(char *s) {
}
InvalidateGraphics();
SS.later.showTW = true;
HideTextEditControl();
edit.meaning = EDIT_NOTHING;
if(!edit.showAgain) {
HideTextEditControl();
edit.meaning = EDIT_NOTHING;
}
}

View File

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

16
ui.h
View File

@ -55,6 +55,7 @@ public:
static const int SCREEN_LIST_OF_STYLES = 6;
static const int SCREEN_STYLE_INFO = 7;
static const int SCREEN_PASTE_TRANSFORMED = 8;
static const int SCREEN_EDIT_VIEW = 9;
typedef struct {
int screen;
@ -116,7 +117,13 @@ public:
static const int EDIT_PASTE_TIMES_REPEATED = 60;
static const int EDIT_PASTE_ANGLE = 61;
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 {
bool showAgain;
int meaning;
int i;
hGroup group;
@ -140,6 +147,7 @@ public:
void ShowStepDimension(void);
void ShowMeshVolume(void);
void ShowPasteTransformed(void);
void ShowEditView(void);
// Special screen, based on selection
void DescribeSelection(void);
@ -179,6 +187,7 @@ public:
static void ScreenBackgroundImage(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 ScreenChangeFixExportColors(int link, DWORD v);
@ -217,10 +226,14 @@ public:
static void ScreenChangeBackgroundColor(int link, DWORD v);
static void ScreenChangeBackgroundImageScale(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 EditControlDoneForConfiguration(char *s);
bool EditControlDoneForPaste(char *s);
bool EditControlDoneForView(char *s);
void EditControlDone(char *s);
};
@ -413,9 +426,6 @@ public:
hEntity normal;
hConstraint constraint;
bool drawLine;
Vector lnA, lnB;
char *description;
} pending;
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
some kind of import