Convert all enumerations to use enum class.

Specifically, take the old code that looks like this:

  class Foo {
    enum { X = 1, Y = 2 };
    int kind;
  }
  ... foo.kind = Foo::X; ...

and convert it to this:

  class Foo {
    enum class Kind : uint32_t { X = 1, Y = 2 };
    Kind kind;
  }
  ... foo.kind = Foo::Kind::X;

(In some cases the enumeration would not be in the class namespace,
such as when it is generally useful.)

The benefits are as follows:
  * The type of the field gives a clear indication of intent, both
    to humans and tools (such as binding generators).
  * The compiler is able to automatically warn when a switch is not
    exhaustive; but this is currently suppressed by the
      default: ssassert(false, ...)
    idiom.
  * Integers and plain enums are weakly type checked: they implicitly
    convert into each other. This can hide bugs where type conversion
    is performed but not intended. Enum classes are strongly type
    checked.
  * Plain enums pollute parent namespaces; enum classes do not.
    Almost every defined enum we have already has a kind of ad-hoc
    namespacing via `NAMESPACE_`, which is now explicit.
  * Plain enums do not have a well-defined ABI size, which is
    important for bindings. Enum classes can have it, if specified.
    We specify the base type for all enums as uint32_t, which is
    a safe choice and allows us to not change the numeric values
    of any variants.

This commit introduces absolutely no functional change to the code,
just renaming and change of types. It handles almost all cases,
except GraphicsWindow::pending.operation, which needs minor
functional change.
This commit is contained in:
EvilSpirit 2016-05-20 14:31:20 +06:00 committed by whitequark
parent 3103728c15
commit f33ddc94fb
49 changed files with 2287 additions and 2241 deletions

View File

@ -82,19 +82,19 @@ void SBsp3::InsertInPlane(bool pos2, STriangle *tr, SMesh *m) {
} }
} }
void SBsp3::InsertHow(int how, STriangle *tr, SMesh *instead) { void SBsp3::InsertHow(BspClass how, STriangle *tr, SMesh *instead) {
switch(how) { switch(how) {
case POS: case BspClass::POS:
if(instead && !pos) goto alt; if(instead && !pos) goto alt;
pos = InsertOrCreate(pos, tr, instead); pos = InsertOrCreate(pos, tr, instead);
break; break;
case NEG: case BspClass::NEG:
if(instead && !neg) goto alt; if(instead && !neg) goto alt;
neg = InsertOrCreate(neg, tr, instead); neg = InsertOrCreate(neg, tr, instead);
break; break;
case COPLANAR: { case BspClass::COPLANAR: {
if(instead) goto alt; if(instead) goto alt;
SBsp3 *m = Alloc(); SBsp3 *m = Alloc();
m->n = n; m->n = n;
@ -109,11 +109,11 @@ void SBsp3::InsertHow(int how, STriangle *tr, SMesh *instead) {
return; return;
alt: alt:
if(how == POS && !(instead->flipNormal)) { if(how == BspClass::POS && !(instead->flipNormal)) {
instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c); instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c);
} else if(how == NEG && instead->flipNormal) { } else if(how == BspClass::NEG && instead->flipNormal) {
instead->AddTriangle(tr->meta, tr->c, tr->b, tr->a); instead->AddTriangle(tr->meta, tr->c, tr->b, tr->a);
} else if(how == COPLANAR) { } else if(how == BspClass::COPLANAR) {
if(edges) { if(edges) {
edges->InsertTriangle(tr, instead, this); edges->InsertTriangle(tr, instead, this);
} else { } else {
@ -126,18 +126,18 @@ alt:
} }
} }
void SBsp3::InsertConvexHow(int how, STriMeta meta, Vector *vertex, int n, void SBsp3::InsertConvexHow(BspClass how, STriMeta meta, Vector *vertex, int n,
SMesh *instead) SMesh *instead)
{ {
switch(how) { switch(how) {
case POS: case BspClass::POS:
if(pos) { if(pos) {
pos = pos->InsertConvex(meta, vertex, n, instead); pos = pos->InsertConvex(meta, vertex, n, instead);
return; return;
} }
break; break;
case NEG: case BspClass::NEG:
if(neg) { if(neg) {
neg = neg->InsertConvex(meta, vertex, n, instead); neg = neg->InsertConvex(meta, vertex, n, instead);
return; return;
@ -197,11 +197,11 @@ SBsp3 *SBsp3::InsertConvex(STriMeta meta, Vector *vertex, int cnt,
} }
if(posc == 0) { if(posc == 0) {
InsertConvexHow(NEG, meta, vertex, cnt, instead); InsertConvexHow(BspClass::NEG, meta, vertex, cnt, instead);
return this; return this;
} }
if(negc == 0) { if(negc == 0) {
InsertConvexHow(POS, meta, vertex, cnt, instead); InsertConvexHow(BspClass::POS, meta, vertex, cnt, instead);
return this; return this;
} }
@ -251,8 +251,8 @@ SBsp3 *SBsp3::InsertConvex(STriMeta meta, Vector *vertex, int cnt,
} }
if(nneg < 3 || npos < 3) goto triangulate; // XXX if(nneg < 3 || npos < 3) goto triangulate; // XXX
InsertConvexHow(NEG, meta, vneg, nneg, instead); InsertConvexHow(BspClass::NEG, meta, vneg, nneg, instead);
InsertConvexHow(POS, meta, vpos, npos, instead); InsertConvexHow(BspClass::POS, meta, vpos, npos, instead);
return this; return this;
triangulate: triangulate:
@ -309,7 +309,7 @@ void SBsp3::Insert(STriangle *tr, SMesh *instead) {
// All vertices in-plane // All vertices in-plane
if(inc == 3) { if(inc == 3) {
InsertHow(COPLANAR, tr, instead); InsertHow(BspClass::COPLANAR, tr, instead);
return; return;
} }
@ -328,9 +328,9 @@ void SBsp3::Insert(STriangle *tr, SMesh *instead) {
} }
if(posc > 0) { if(posc > 0) {
InsertHow(POS, tr, instead); InsertHow(BspClass::POS, tr, instead);
} else { } else {
InsertHow(NEG, tr, instead); InsertHow(BspClass::NEG, tr, instead);
} }
return; return;
} }
@ -351,11 +351,11 @@ void SBsp3::Insert(STriangle *tr, SMesh *instead) {
STriangle ctri = STriangle::From(tr->meta, c, a, bPc); STriangle ctri = STriangle::From(tr->meta, c, a, bPc);
if(bpos) { if(bpos) {
InsertHow(POS, &btri, instead); InsertHow(BspClass::POS, &btri, instead);
InsertHow(NEG, &ctri, instead); InsertHow(BspClass::NEG, &ctri, instead);
} else { } else {
InsertHow(POS, &ctri, instead); InsertHow(BspClass::POS, &ctri, instead);
InsertHow(NEG, &btri, instead); InsertHow(BspClass::NEG, &btri, instead);
} }
if(!instead) { if(!instead) {
@ -387,11 +387,11 @@ void SBsp3::Insert(STriangle *tr, SMesh *instead) {
Vector quad[4] = { aPb, b, c, cPa }; Vector quad[4] = { aPb, b, c, cPa };
if(posc == 2 && negc == 1) { if(posc == 2 && negc == 1) {
InsertConvexHow(POS, tr->meta, quad, 4, instead); InsertConvexHow(BspClass::POS, tr->meta, quad, 4, instead);
InsertHow(NEG, &alone, instead); InsertHow(BspClass::NEG, &alone, instead);
} else { } else {
InsertConvexHow(NEG, tr->meta, quad, 4, instead); InsertConvexHow(BspClass::NEG, tr->meta, quad, 4, instead);
InsertHow(POS, &alone, instead); InsertHow(BspClass::POS, &alone, instead);
} }
if(!instead) { if(!instead) {
SEdge se = SEdge::From(aPb, cPa); SEdge se = SEdge::From(aPb, cPa);
@ -550,9 +550,9 @@ void SBsp2::InsertEdge(SEdge *nedge, Vector nnp, Vector out) {
ssassert(false, "Impossible"); ssassert(false, "Impossible");
} }
void SBsp2::InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3) { void SBsp2::InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3) {
switch(how) { switch(how) {
case POS: case BspClass::POS:
if(pos) { if(pos) {
pos->InsertTriangle(tr, m, bsp3); pos->InsertTriangle(tr, m, bsp3);
} else { } else {
@ -560,7 +560,7 @@ void SBsp2::InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3) {
} }
break; break;
case NEG: case BspClass::NEG:
if(neg) { if(neg) {
neg->InsertTriangle(tr, m, bsp3); neg->InsertTriangle(tr, m, bsp3);
} else { } else {
@ -598,9 +598,9 @@ void SBsp2::InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3) {
// No split required // No split required
if(posc == 0 || negc == 0) { if(posc == 0 || negc == 0) {
if(posc > 0) { if(posc > 0) {
InsertTriangleHow(POS, tr, m, bsp3); InsertTriangleHow(BspClass::POS, tr, m, bsp3);
} else { } else {
InsertTriangleHow(NEG, tr, m, bsp3); InsertTriangleHow(BspClass::NEG, tr, m, bsp3);
} }
return; return;
} }
@ -621,11 +621,11 @@ void SBsp2::InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3) {
STriangle ctri = STriangle::From(tr->meta, c, a, bPc); STriangle ctri = STriangle::From(tr->meta, c, a, bPc);
if(bpos) { if(bpos) {
InsertTriangleHow(POS, &btri, m, bsp3); InsertTriangleHow(BspClass::POS, &btri, m, bsp3);
InsertTriangleHow(NEG, &ctri, m, bsp3); InsertTriangleHow(BspClass::NEG, &ctri, m, bsp3);
} else { } else {
InsertTriangleHow(POS, &ctri, m, bsp3); InsertTriangleHow(BspClass::POS, &ctri, m, bsp3);
InsertTriangleHow(NEG, &btri, m, bsp3); InsertTriangleHow(BspClass::NEG, &btri, m, bsp3);
} }
return; return;
@ -653,13 +653,13 @@ void SBsp2::InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3) {
STriangle quad2 = STriangle::From(tr->meta, aPb, c, cPa); STriangle quad2 = STriangle::From(tr->meta, aPb, c, cPa);
if(posc == 2 && negc == 1) { if(posc == 2 && negc == 1) {
InsertTriangleHow(POS, &quad1, m, bsp3); InsertTriangleHow(BspClass::POS, &quad1, m, bsp3);
InsertTriangleHow(POS, &quad2, m, bsp3); InsertTriangleHow(BspClass::POS, &quad2, m, bsp3);
InsertTriangleHow(NEG, &alone, m, bsp3); InsertTriangleHow(BspClass::NEG, &alone, m, bsp3);
} else { } else {
InsertTriangleHow(NEG, &quad1, m, bsp3); InsertTriangleHow(BspClass::NEG, &quad1, m, bsp3);
InsertTriangleHow(NEG, &quad2, m, bsp3); InsertTriangleHow(BspClass::NEG, &quad2, m, bsp3);
InsertTriangleHow(POS, &alone, m, bsp3); InsertTriangleHow(BspClass::POS, &alone, m, bsp3);
} }
return; return;

View File

@ -85,13 +85,14 @@ void GraphicsWindow::CopySelection() {
// Work only on entities that have requests that will generate them. // Work only on entities that have requests that will generate them.
Entity *e = SK.GetEntity(s->entity); Entity *e = SK.GetEntity(s->entity);
bool hasDistance; bool hasDistance;
int req, pts; Request::Type req;
int pts;
if(!EntReqTable::GetEntityInfo(e->type, e->extraPoints, if(!EntReqTable::GetEntityInfo(e->type, e->extraPoints,
&req, &pts, NULL, &hasDistance)) &req, &pts, NULL, &hasDistance))
{ {
continue; continue;
} }
if(req == Request::WORKPLANE) continue; if(req == Request::Type::WORKPLANE) continue;
ClipboardRequest cr = {}; ClipboardRequest cr = {};
cr.type = req; cr.type = req;
@ -122,7 +123,7 @@ void GraphicsWindow::CopySelection() {
if(!s->constraint.v) continue; if(!s->constraint.v) continue;
Constraint *c = SK.GetConstraint(s->constraint); Constraint *c = SK.GetConstraint(s->constraint);
if(c->type == Constraint::COMMENT) { if(c->type == Constraint::Type::COMMENT) {
SS.clipboard.c.Add(c); SS.clipboard.c.Add(c);
} }
} }
@ -135,7 +136,7 @@ void GraphicsWindow::CopySelection() {
!SS.clipboard.ContainsEntity(c->entityB) || !SS.clipboard.ContainsEntity(c->entityB) ||
!SS.clipboard.ContainsEntity(c->entityC) || !SS.clipboard.ContainsEntity(c->entityC) ||
!SS.clipboard.ContainsEntity(c->entityD) || !SS.clipboard.ContainsEntity(c->entityD) ||
c->type == Constraint::COMMENT) { c->type == Constraint::Type::COMMENT) {
continue; continue;
} }
SS.clipboard.c.Add(c); SS.clipboard.c.Add(c);
@ -161,7 +162,7 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
r->construction = cr->construction; r->construction = cr->construction;
// Need to regen to get the right number of points, if extraPoints // Need to regen to get the right number of points, if extraPoints
// changed. // changed.
SS.GenerateAll(SolveSpaceUI::GENERATE_REGEN); SS.GenerateAll(SolveSpaceUI::Generate::REGEN);
SS.MarkGroupDirty(r->group); SS.MarkGroupDirty(r->group);
bool hasDistance; bool hasDistance;
int i, pts; int i, pts;
@ -214,7 +215,7 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
c.disp = cc->disp; c.disp = cc->disp;
c.comment = cc->comment; c.comment = cc->comment;
hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false); hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false);
if(c.type == Constraint::COMMENT) { if(c.type == Constraint::Type::COMMENT) {
SK.GetConstraint(hc)->disp.offset = SK.GetConstraint(hc)->disp.offset.Plus(trans); SK.GetConstraint(hc)->disp.offset = SK.GetConstraint(hc)->disp.offset.Plus(trans);
MakeSelected(hc); MakeSelected(hc);
} }
@ -223,15 +224,15 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
SS.ScheduleGenerateAll(); SS.ScheduleGenerateAll();
} }
void GraphicsWindow::MenuClipboard(int id) { void GraphicsWindow::MenuClipboard(Command id) {
if(id != MNU_DELETE && !SS.GW.LockedInWorkplane()) { if(id != Command::DELETE && !SS.GW.LockedInWorkplane()) {
Error("Cut, paste, and copy work only in a workplane.\n\n" Error("Cut, paste, and copy work only in a workplane.\n\n"
"Select one with Sketch -> In Workplane."); "Select one with Sketch -> In Workplane.");
return; return;
} }
switch(id) { switch(id) {
case MNU_PASTE: { case Command::PASTE: {
SS.UndoRemember(); SS.UndoRemember();
Vector trans = SS.GW.projRight.ScaledBy(80/SS.GW.scale).Plus( Vector trans = SS.GW.projRight.ScaledBy(80/SS.GW.scale).Plus(
SS.GW.projUp .ScaledBy(40/SS.GW.scale)); SS.GW.projUp .ScaledBy(40/SS.GW.scale));
@ -240,7 +241,7 @@ void GraphicsWindow::MenuClipboard(int id) {
break; break;
} }
case MNU_PASTE_TRANSFORM: { case Command::PASTE_TRANSFORM: {
if(SS.clipboard.r.n == 0) { if(SS.clipboard.r.n == 0) {
Error("Clipboard is empty; nothing to paste."); Error("Clipboard is empty; nothing to paste.");
break; break;
@ -253,24 +254,24 @@ void GraphicsWindow::MenuClipboard(int id) {
SS.TW.shown.paste.theta = 0; SS.TW.shown.paste.theta = 0;
SS.TW.shown.paste.origin = p; SS.TW.shown.paste.origin = p;
SS.TW.shown.paste.scale = 1; SS.TW.shown.paste.scale = 1;
SS.TW.GoToScreen(TextWindow::SCREEN_PASTE_TRANSFORMED); SS.TW.GoToScreen(TextWindow::Screen::PASTE_TRANSFORMED);
SS.GW.ForceTextWindowShown(); SS.GW.ForceTextWindowShown();
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
} }
case MNU_COPY: case Command::COPY:
SS.GW.CopySelection(); SS.GW.CopySelection();
SS.GW.ClearSelection(); SS.GW.ClearSelection();
break; break;
case MNU_CUT: case Command::CUT:
SS.UndoRemember(); SS.UndoRemember();
SS.GW.CopySelection(); SS.GW.CopySelection();
SS.GW.DeleteSelection(); SS.GW.DeleteSelection();
break; break;
case MNU_DELETE: case Command::DELETE:
SS.UndoRemember(); SS.UndoRemember();
SS.GW.DeleteSelection(); SS.GW.DeleteSelection();
break; break;
@ -282,7 +283,7 @@ void GraphicsWindow::MenuClipboard(int id) {
bool TextWindow::EditControlDoneForPaste(const char *s) { bool TextWindow::EditControlDoneForPaste(const char *s) {
Expr *e; Expr *e;
switch(edit.meaning) { switch(edit.meaning) {
case EDIT_PASTE_TIMES_REPEATED: { case Edit::PASTE_TIMES_REPEATED: {
e = Expr::From(s, true); e = Expr::From(s, true);
if(!e) break; if(!e) break;
int v = (int)e->Eval(); int v = (int)e->Eval();
@ -293,13 +294,13 @@ bool TextWindow::EditControlDoneForPaste(const char *s) {
} }
break; break;
} }
case EDIT_PASTE_ANGLE: case Edit::PASTE_ANGLE:
e = Expr::From(s, true); e = Expr::From(s, true);
if(!e) break; if(!e) break;
shown.paste.theta = WRAP_SYMMETRIC((e->Eval())*PI/180, 2*PI); shown.paste.theta = WRAP_SYMMETRIC((e->Eval())*PI/180, 2*PI);
break; break;
case EDIT_PASTE_SCALE: { case Edit::PASTE_SCALE: {
e = Expr::From(s, true); e = Expr::From(s, true);
double v = e->Eval(); double v = e->Eval();
if(fabs(v) > 1e-6) { if(fabs(v) > 1e-6) {
@ -320,17 +321,17 @@ void TextWindow::ScreenChangePasteTransformed(int link, uint32_t v) {
switch(link) { switch(link) {
case 't': case 't':
SS.TW.ShowEditControl(13, ssprintf("%d", SS.TW.shown.paste.times)); SS.TW.ShowEditControl(13, ssprintf("%d", SS.TW.shown.paste.times));
SS.TW.edit.meaning = EDIT_PASTE_TIMES_REPEATED; SS.TW.edit.meaning = Edit::PASTE_TIMES_REPEATED;
break; break;
case 'r': case 'r':
SS.TW.ShowEditControl(13, ssprintf("%.3f", SS.TW.shown.paste.theta*180/PI)); SS.TW.ShowEditControl(13, ssprintf("%.3f", SS.TW.shown.paste.theta*180/PI));
SS.TW.edit.meaning = EDIT_PASTE_ANGLE; SS.TW.edit.meaning = Edit::PASTE_ANGLE;
break; break;
case 's': case 's':
SS.TW.ShowEditControl(13, ssprintf("%.3f", SS.TW.shown.paste.scale)); SS.TW.ShowEditControl(13, ssprintf("%.3f", SS.TW.shown.paste.scale));
SS.TW.edit.meaning = EDIT_PASTE_SCALE; SS.TW.edit.meaning = Edit::PASTE_SCALE;
break; break;
} }
} }
@ -394,7 +395,7 @@ void TextWindow::ScreenPasteTransformed(int link, uint32_t v) {
SS.GW.PasteClipboard(t, theta, SS.TW.shown.paste.scale); SS.GW.PasteClipboard(t, theta, SS.TW.shown.paste.scale);
} }
SS.TW.GoToScreen(SCREEN_LIST_OF_GROUPS); SS.TW.GoToScreen(Screen::LIST_OF_GROUPS);
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
} }

View File

@ -8,70 +8,70 @@
void TextWindow::ScreenChangeLightDirection(int link, uint32_t v) { void TextWindow::ScreenChangeLightDirection(int link, uint32_t v) {
SS.TW.ShowEditControl(8, ssprintf("%.2f, %.2f, %.2f", CO(SS.lightDir[v]))); SS.TW.ShowEditControl(8, ssprintf("%.2f, %.2f, %.2f", CO(SS.lightDir[v])));
SS.TW.edit.meaning = EDIT_LIGHT_DIRECTION; SS.TW.edit.meaning = Edit::LIGHT_DIRECTION;
SS.TW.edit.i = v; SS.TW.edit.i = v;
} }
void TextWindow::ScreenChangeLightIntensity(int link, uint32_t v) { void TextWindow::ScreenChangeLightIntensity(int link, uint32_t v) {
SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.lightIntensity[v])); SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.lightIntensity[v]));
SS.TW.edit.meaning = EDIT_LIGHT_INTENSITY; SS.TW.edit.meaning = Edit::LIGHT_INTENSITY;
SS.TW.edit.i = v; SS.TW.edit.i = v;
} }
void TextWindow::ScreenChangeColor(int link, uint32_t v) { void TextWindow::ScreenChangeColor(int link, uint32_t v) {
SS.TW.ShowEditControlWithColorPicker(13, SS.modelColor[v]); SS.TW.ShowEditControlWithColorPicker(13, SS.modelColor[v]);
SS.TW.edit.meaning = EDIT_COLOR; SS.TW.edit.meaning = Edit::COLOR;
SS.TW.edit.i = v; SS.TW.edit.i = v;
} }
void TextWindow::ScreenChangeChordTolerance(int link, uint32_t v) { void TextWindow::ScreenChangeChordTolerance(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%lg", SS.chordTol)); SS.TW.ShowEditControl(3, ssprintf("%lg", SS.chordTol));
SS.TW.edit.meaning = EDIT_CHORD_TOLERANCE; SS.TW.edit.meaning = Edit::CHORD_TOLERANCE;
SS.TW.edit.i = 0; SS.TW.edit.i = 0;
} }
void TextWindow::ScreenChangeMaxSegments(int link, uint32_t v) { void TextWindow::ScreenChangeMaxSegments(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%d", SS.maxSegments)); SS.TW.ShowEditControl(3, ssprintf("%d", SS.maxSegments));
SS.TW.edit.meaning = EDIT_MAX_SEGMENTS; SS.TW.edit.meaning = Edit::MAX_SEGMENTS;
SS.TW.edit.i = 0; SS.TW.edit.i = 0;
} }
void TextWindow::ScreenChangeExportChordTolerance(int link, uint32_t v) { void TextWindow::ScreenChangeExportChordTolerance(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%lg", SS.exportChordTol)); SS.TW.ShowEditControl(3, ssprintf("%lg", SS.exportChordTol));
SS.TW.edit.meaning = EDIT_CHORD_TOLERANCE; SS.TW.edit.meaning = Edit::CHORD_TOLERANCE;
SS.TW.edit.i = 1; SS.TW.edit.i = 1;
} }
void TextWindow::ScreenChangeExportMaxSegments(int link, uint32_t v) { void TextWindow::ScreenChangeExportMaxSegments(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%d", SS.exportMaxSegments)); SS.TW.ShowEditControl(3, ssprintf("%d", SS.exportMaxSegments));
SS.TW.edit.meaning = EDIT_MAX_SEGMENTS; SS.TW.edit.meaning = Edit::MAX_SEGMENTS;
SS.TW.edit.i = 1; SS.TW.edit.i = 1;
} }
void TextWindow::ScreenChangeCameraTangent(int link, uint32_t v) { void TextWindow::ScreenChangeCameraTangent(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%.3f", 1000*SS.cameraTangent)); SS.TW.ShowEditControl(3, ssprintf("%.3f", 1000*SS.cameraTangent));
SS.TW.edit.meaning = EDIT_CAMERA_TANGENT; SS.TW.edit.meaning = Edit::CAMERA_TANGENT;
} }
void TextWindow::ScreenChangeGridSpacing(int link, uint32_t v) { void TextWindow::ScreenChangeGridSpacing(int link, uint32_t v) {
SS.TW.ShowEditControl(3, SS.MmToString(SS.gridSpacing)); SS.TW.ShowEditControl(3, SS.MmToString(SS.gridSpacing));
SS.TW.edit.meaning = EDIT_GRID_SPACING; SS.TW.edit.meaning = Edit::GRID_SPACING;
} }
void TextWindow::ScreenChangeDigitsAfterDecimal(int link, uint32_t v) { void TextWindow::ScreenChangeDigitsAfterDecimal(int link, uint32_t v) {
SS.TW.ShowEditControl(3, ssprintf("%d", SS.UnitDigitsAfterDecimal())); SS.TW.ShowEditControl(3, ssprintf("%d", SS.UnitDigitsAfterDecimal()));
SS.TW.edit.meaning = EDIT_DIGITS_AFTER_DECIMAL; SS.TW.edit.meaning = Edit::DIGITS_AFTER_DECIMAL;
} }
void TextWindow::ScreenChangeExportScale(int link, uint32_t v) { void TextWindow::ScreenChangeExportScale(int link, uint32_t v) {
SS.TW.ShowEditControl(5, ssprintf("%.3f", (double)SS.exportScale)); SS.TW.ShowEditControl(5, ssprintf("%.3f", (double)SS.exportScale));
SS.TW.edit.meaning = EDIT_EXPORT_SCALE; SS.TW.edit.meaning = Edit::EXPORT_SCALE;
} }
void TextWindow::ScreenChangeExportOffset(int link, uint32_t v) { void TextWindow::ScreenChangeExportOffset(int link, uint32_t v) {
SS.TW.ShowEditControl(3, SS.MmToString(SS.exportOffset)); SS.TW.ShowEditControl(3, SS.MmToString(SS.exportOffset));
SS.TW.edit.meaning = EDIT_EXPORT_OFFSET; SS.TW.edit.meaning = Edit::EXPORT_OFFSET;
} }
void TextWindow::ScreenChangeFixExportColors(int link, uint32_t v) { void TextWindow::ScreenChangeFixExportColors(int link, uint32_t v) {
@ -125,7 +125,7 @@ void TextWindow::ScreenChangeCanvasSize(int link, uint32_t v) {
int col = 13; int col = 13;
if(v < 10) col = 11; if(v < 10) col = 11;
SS.TW.ShowEditControl(col, SS.MmToString(d)); SS.TW.ShowEditControl(col, SS.MmToString(d));
SS.TW.edit.meaning = EDIT_CANVAS_SIZE; SS.TW.edit.meaning = Edit::CANVAS_SIZE;
SS.TW.edit.i = v; SS.TW.edit.i = v;
} }
@ -133,22 +133,22 @@ void TextWindow::ScreenChangeGCodeParameter(int link, uint32_t v) {
std::string buf; std::string buf;
switch(link) { switch(link) {
case 'd': case 'd':
SS.TW.edit.meaning = EDIT_G_CODE_DEPTH; SS.TW.edit.meaning = Edit::G_CODE_DEPTH;
buf += SS.MmToString(SS.gCode.depth); buf += SS.MmToString(SS.gCode.depth);
break; break;
case 's': case 's':
SS.TW.edit.meaning = EDIT_G_CODE_PASSES; SS.TW.edit.meaning = Edit::G_CODE_PASSES;
buf += std::to_string(SS.gCode.passes); buf += std::to_string(SS.gCode.passes);
break; break;
case 'F': case 'F':
SS.TW.edit.meaning = EDIT_G_CODE_FEED; SS.TW.edit.meaning = Edit::G_CODE_FEED;
buf += SS.MmToString(SS.gCode.feed); buf += SS.MmToString(SS.gCode.feed);
break; break;
case 'P': case 'P':
SS.TW.edit.meaning = EDIT_G_CODE_PLUNGE_FEED; SS.TW.edit.meaning = Edit::G_CODE_PLUNGE_FEED;
buf += SS.MmToString(SS.gCode.plungeFeed); buf += SS.MmToString(SS.gCode.plungeFeed);
break; break;
} }
@ -157,7 +157,7 @@ void TextWindow::ScreenChangeGCodeParameter(int link, uint32_t v) {
void TextWindow::ScreenChangeAutosaveInterval(int link, uint32_t v) { void TextWindow::ScreenChangeAutosaveInterval(int link, uint32_t v) {
SS.TW.ShowEditControl(3, std::to_string(SS.autosaveInterval)); SS.TW.ShowEditControl(3, std::to_string(SS.autosaveInterval));
SS.TW.edit.meaning = EDIT_AUTOSAVE_INTERVAL; SS.TW.edit.meaning = Edit::AUTOSAVE_INTERVAL;
} }
void TextWindow::ShowConfiguration() { void TextWindow::ShowConfiguration() {
@ -310,12 +310,12 @@ void TextWindow::ShowConfiguration() {
bool TextWindow::EditControlDoneForConfiguration(const char *s) { bool TextWindow::EditControlDoneForConfiguration(const char *s) {
switch(edit.meaning) { switch(edit.meaning) {
case EDIT_LIGHT_INTENSITY: case Edit::LIGHT_INTENSITY:
SS.lightIntensity[edit.i] = min(1.0, max(0.0, atof(s))); SS.lightIntensity[edit.i] = min(1.0, max(0.0, atof(s)));
InvalidateGraphics(); InvalidateGraphics();
break; break;
case EDIT_LIGHT_DIRECTION: { case Edit::LIGHT_DIRECTION: {
double x, y, z; double x, y, z;
if(sscanf(s, "%lf, %lf, %lf", &x, &y, &z)==3) { if(sscanf(s, "%lf, %lf, %lf", &x, &y, &z)==3) {
SS.lightDir[edit.i] = Vector::From(x, y, z); SS.lightDir[edit.i] = Vector::From(x, y, z);
@ -325,7 +325,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
InvalidateGraphics(); InvalidateGraphics();
break; break;
} }
case EDIT_COLOR: { case Edit::COLOR: {
Vector rgb; Vector rgb;
if(sscanf(s, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { if(sscanf(s, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) {
rgb = rgb.ClampWithin(0, 1); rgb = rgb.ClampWithin(0, 1);
@ -335,25 +335,25 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
} }
break; break;
} }
case EDIT_CHORD_TOLERANCE: { case Edit::CHORD_TOLERANCE: {
if(edit.i == 0) { if(edit.i == 0) {
SS.chordTol = max(0.0, atof(s)); SS.chordTol = max(0.0, atof(s));
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
} else { } else {
SS.exportChordTol = max(0.0, atof(s)); SS.exportChordTol = max(0.0, atof(s));
} }
break; break;
} }
case EDIT_MAX_SEGMENTS: { case Edit::MAX_SEGMENTS: {
if(edit.i == 0) { if(edit.i == 0) {
SS.maxSegments = min(1000, max(7, atoi(s))); SS.maxSegments = min(1000, max(7, atoi(s)));
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
} else { } else {
SS.exportMaxSegments = min(1000, max(7, atoi(s))); SS.exportMaxSegments = min(1000, max(7, atoi(s)));
} }
break; break;
} }
case EDIT_CAMERA_TANGENT: { case Edit::CAMERA_TANGENT: {
SS.cameraTangent = (min(2.0, max(0.0, atof(s))))/1000.0; SS.cameraTangent = (min(2.0, max(0.0, atof(s))))/1000.0;
if(!SS.usePerspectiveProj) { if(!SS.usePerspectiveProj) {
Message("The perspective factor will have no effect until you " Message("The perspective factor will have no effect until you "
@ -362,12 +362,12 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
InvalidateGraphics(); InvalidateGraphics();
break; break;
} }
case EDIT_GRID_SPACING: { case Edit::GRID_SPACING: {
SS.gridSpacing = (float)min(1e4, max(1e-3, SS.StringToMm(s))); SS.gridSpacing = (float)min(1e4, max(1e-3, SS.StringToMm(s)));
InvalidateGraphics(); InvalidateGraphics();
break; break;
} }
case EDIT_DIGITS_AFTER_DECIMAL: { case Edit::DIGITS_AFTER_DECIMAL: {
int v = atoi(s); int v = atoi(s);
if(v < 0 || v > 8) { if(v < 0 || v > 8) {
Error("Specify between 0 and 8 digits after the decimal."); Error("Specify between 0 and 8 digits after the decimal.");
@ -377,7 +377,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
InvalidateGraphics(); InvalidateGraphics();
break; break;
} }
case EDIT_EXPORT_SCALE: { case Edit::EXPORT_SCALE: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double ev = e->Eval(); double ev = e->Eval();
@ -389,7 +389,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
} }
break; break;
} }
case EDIT_EXPORT_OFFSET: { case Edit::EXPORT_OFFSET: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double ev = SS.ExprToMm(e); double ev = SS.ExprToMm(e);
@ -401,7 +401,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
} }
break; break;
} }
case EDIT_CANVAS_SIZE: { case Edit::CANVAS_SIZE: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(!e) { if(!e) {
break; break;
@ -420,28 +420,28 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
} }
break; break;
} }
case EDIT_G_CODE_DEPTH: { case Edit::G_CODE_DEPTH: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) SS.gCode.depth = (float)SS.ExprToMm(e); if(e) SS.gCode.depth = (float)SS.ExprToMm(e);
break; break;
} }
case EDIT_G_CODE_PASSES: { case Edit::G_CODE_PASSES: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) SS.gCode.passes = (int)(e->Eval()); if(e) SS.gCode.passes = (int)(e->Eval());
SS.gCode.passes = max(1, min(1000, SS.gCode.passes)); SS.gCode.passes = max(1, min(1000, SS.gCode.passes));
break; break;
} }
case EDIT_G_CODE_FEED: { case Edit::G_CODE_FEED: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) SS.gCode.feed = (float)SS.ExprToMm(e); if(e) SS.gCode.feed = (float)SS.ExprToMm(e);
break; break;
} }
case EDIT_G_CODE_PLUNGE_FEED: { case Edit::G_CODE_PLUNGE_FEED: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) SS.gCode.plungeFeed = (float)SS.ExprToMm(e); if(e) SS.gCode.plungeFeed = (float)SS.ExprToMm(e);
break; break;
} }
case EDIT_AUTOSAVE_INTERVAL: { case Edit::AUTOSAVE_INTERVAL: {
int interval; int interval;
if(sscanf(s, "%d", &interval)==1) { if(sscanf(s, "%d", &interval)==1) {
if(interval >= 1) { if(interval >= 1) {

View File

@ -9,41 +9,41 @@
std::string Constraint::DescriptionString() const { std::string Constraint::DescriptionString() const {
const char *s; const char *s;
switch(type) { switch(type) {
case POINTS_COINCIDENT: s = "pts-coincident"; break; case Type::POINTS_COINCIDENT: s = "pts-coincident"; break;
case PT_PT_DISTANCE: s = "pt-pt-distance"; break; case Type::PT_PT_DISTANCE: s = "pt-pt-distance"; break;
case PT_LINE_DISTANCE: s = "pt-line-distance"; break; case Type::PT_LINE_DISTANCE: s = "pt-line-distance"; break;
case PT_PLANE_DISTANCE: s = "pt-plane-distance"; break; case Type::PT_PLANE_DISTANCE: s = "pt-plane-distance"; break;
case PT_FACE_DISTANCE: s = "pt-face-distance"; break; case Type::PT_FACE_DISTANCE: s = "pt-face-distance"; break;
case PROJ_PT_DISTANCE: s = "proj-pt-pt-distance"; break; case Type::PROJ_PT_DISTANCE: s = "proj-pt-pt-distance"; break;
case PT_IN_PLANE: s = "pt-in-plane"; break; case Type::PT_IN_PLANE: s = "pt-in-plane"; break;
case PT_ON_LINE: s = "pt-on-line"; break; case Type::PT_ON_LINE: s = "pt-on-line"; break;
case PT_ON_FACE: s = "pt-on-face"; break; case Type::PT_ON_FACE: s = "pt-on-face"; break;
case EQUAL_LENGTH_LINES: s = "eq-length"; break; case Type::EQUAL_LENGTH_LINES: s = "eq-length"; break;
case EQ_LEN_PT_LINE_D: s = "eq-length-and-pt-ln-dist"; break; case Type::EQ_LEN_PT_LINE_D: s = "eq-length-and-pt-ln-dist"; break;
case EQ_PT_LN_DISTANCES: s = "eq-pt-line-distances"; break; case Type::EQ_PT_LN_DISTANCES: s = "eq-pt-line-distances"; break;
case LENGTH_RATIO: s = "length-ratio"; break; case Type::LENGTH_RATIO: s = "length-ratio"; break;
case LENGTH_DIFFERENCE: s = "length-difference"; break; case Type::LENGTH_DIFFERENCE: s = "length-difference"; break;
case SYMMETRIC: s = "symmetric"; break; case Type::SYMMETRIC: s = "symmetric"; break;
case SYMMETRIC_HORIZ: s = "symmetric-h"; break; case Type::SYMMETRIC_HORIZ: s = "symmetric-h"; break;
case SYMMETRIC_VERT: s = "symmetric-v"; break; case Type::SYMMETRIC_VERT: s = "symmetric-v"; break;
case SYMMETRIC_LINE: s = "symmetric-line"; break; case Type::SYMMETRIC_LINE: s = "symmetric-line"; break;
case AT_MIDPOINT: s = "at-midpoint"; break; case Type::AT_MIDPOINT: s = "at-midpoint"; break;
case HORIZONTAL: s = "horizontal"; break; case Type::HORIZONTAL: s = "horizontal"; break;
case VERTICAL: s = "vertical"; break; case Type::VERTICAL: s = "vertical"; break;
case DIAMETER: s = "diameter"; break; case Type::DIAMETER: s = "diameter"; break;
case PT_ON_CIRCLE: s = "pt-on-circle"; break; case Type::PT_ON_CIRCLE: s = "pt-on-circle"; break;
case SAME_ORIENTATION: s = "same-orientation"; break; case Type::SAME_ORIENTATION: s = "same-orientation"; break;
case ANGLE: s = "angle"; break; case Type::ANGLE: s = "angle"; break;
case PARALLEL: s = "parallel"; break; case Type::PARALLEL: s = "parallel"; break;
case ARC_LINE_TANGENT: s = "arc-line-tangent"; break; case Type::ARC_LINE_TANGENT: s = "arc-line-tangent"; break;
case CUBIC_LINE_TANGENT: s = "cubic-line-tangent"; break; case Type::CUBIC_LINE_TANGENT: s = "cubic-line-tangent"; break;
case CURVE_CURVE_TANGENT: s = "curve-curve-tangent"; break; case Type::CURVE_CURVE_TANGENT: s = "curve-curve-tangent"; break;
case PERPENDICULAR: s = "perpendicular"; break; case Type::PERPENDICULAR: s = "perpendicular"; break;
case EQUAL_RADIUS: s = "eq-radius"; break; case Type::EQUAL_RADIUS: s = "eq-radius"; break;
case EQUAL_ANGLE: s = "eq-angle"; break; case Type::EQUAL_ANGLE: s = "eq-angle"; break;
case EQUAL_LINE_ARC_LEN: s = "eq-line-len-arc-len"; break; case Type::EQUAL_LINE_ARC_LEN: s = "eq-line-len-arc-len"; break;
case WHERE_DRAGGED: s = "lock-where-dragged"; break; case Type::WHERE_DRAGGED: s = "lock-where-dragged"; break;
case COMMENT: s = "comment"; break; case Type::COMMENT: s = "comment"; break;
default: s = "???"; break; default: s = "???"; break;
} }
@ -56,7 +56,7 @@ std::string Constraint::DescriptionString() const {
// Delete all constraints with the specified type, entityA, ptA. We use this // Delete all constraints with the specified type, entityA, ptA. We use this
// when auto-removing constraints that would become redundant. // when auto-removing constraints that would become redundant.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Constraint::DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA) void Constraint::DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA)
{ {
SK.constraint.ClearTags(); SK.constraint.ClearTags();
for(int i = 0; i < SK.constraint.n; i++) { for(int i = 0; i < SK.constraint.n; i++) {
@ -89,7 +89,7 @@ hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
return c->h; return c->h;
} }
hConstraint Constraint::Constrain(int type, hEntity ptA, hEntity ptB, hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity ptB,
hEntity entityA, hEntity entityB, hEntity entityA, hEntity entityB,
bool other, bool other2) bool other, bool other2)
{ {
@ -106,16 +106,16 @@ hConstraint Constraint::Constrain(int type, hEntity ptA, hEntity ptB,
return AddConstraint(&c, false); return AddConstraint(&c, false);
} }
hConstraint Constraint::Constrain(int type, hEntity ptA, hEntity ptB, hEntity entityA){ hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA){
return Constrain(type, ptA, ptB, entityA, Entity::NO_ENTITY, false, false); return Constrain(type, ptA, ptB, entityA, Entity::NO_ENTITY, false, false);
} }
hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) { hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
return Constrain(POINTS_COINCIDENT, ptA, ptB, return Constrain(Type::POINTS_COINCIDENT, ptA, ptB,
Entity::NO_ENTITY, Entity::NO_ENTITY, false, false); Entity::NO_ENTITY, Entity::NO_ENTITY, false, false);
} }
void Constraint::MenuConstrain(int id) { void Constraint::MenuConstrain(Command id) {
Constraint c = {}; Constraint c = {};
c.group = SS.GW.activeGroup; c.group = SS.GW.activeGroup;
c.workplane = SS.GW.ActiveWorkplane(); c.workplane = SS.GW.ActiveWorkplane();
@ -124,36 +124,36 @@ void Constraint::MenuConstrain(int id) {
#define gs (SS.GW.gs) #define gs (SS.GW.gs)
switch(id) { switch(id) {
case GraphicsWindow::MNU_DISTANCE_DIA: case Command::DISTANCE_DIA:
case GraphicsWindow::MNU_REF_DISTANCE: { case Command::REF_DISTANCE: {
if(gs.points == 2 && gs.n == 2) { if(gs.points == 2 && gs.n == 2) {
c.type = PT_PT_DISTANCE; c.type = Type::PT_PT_DISTANCE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.ptB = gs.point[1]; c.ptB = gs.point[1];
} else if(gs.lineSegments == 1 && gs.n == 1) { } else if(gs.lineSegments == 1 && gs.n == 1) {
c.type = PT_PT_DISTANCE; c.type = Type::PT_PT_DISTANCE;
Entity *e = SK.GetEntity(gs.entity[0]); Entity *e = SK.GetEntity(gs.entity[0]);
c.ptA = e->point[0]; c.ptA = e->point[0];
c.ptB = e->point[1]; c.ptB = e->point[1];
} else if(gs.vectors == 1 && gs.points == 2 && gs.n == 3) { } else if(gs.vectors == 1 && gs.points == 2 && gs.n == 3) {
c.type = PROJ_PT_DISTANCE; c.type = Type::PROJ_PT_DISTANCE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.ptB = gs.point[1]; c.ptB = gs.point[1];
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
} else if(gs.workplanes == 1 && gs.points == 1 && gs.n == 2) { } else if(gs.workplanes == 1 && gs.points == 1 && gs.n == 2) {
c.type = PT_PLANE_DISTANCE; c.type = Type::PT_PLANE_DISTANCE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
} else if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) {
c.type = PT_LINE_DISTANCE; c.type = Type::PT_LINE_DISTANCE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
} else if(gs.faces == 1 && gs.points == 1 && gs.n == 2) { } else if(gs.faces == 1 && gs.points == 1 && gs.n == 2) {
c.type = PT_FACE_DISTANCE; c.type = Type::PT_FACE_DISTANCE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.face[0]; c.entityA = gs.face[0];
} else if(gs.circlesOrArcs == 1 && gs.n == 1) { } else if(gs.circlesOrArcs == 1 && gs.n == 1) {
c.type = DIAMETER; c.type = Type::DIAMETER;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
} else { } else {
Error( Error(
@ -168,7 +168,7 @@ void Constraint::MenuConstrain(int id) {
" * a circle or an arc (diameter)\n"); " * a circle or an arc (diameter)\n");
return; return;
} }
if(c.type == PT_PT_DISTANCE || c.type == PROJ_PT_DISTANCE) { if(c.type == Type::PT_PT_DISTANCE || c.type == Type::PROJ_PT_DISTANCE) {
Vector n = SS.GW.projRight.Cross(SS.GW.projUp); Vector n = SS.GW.projRight.Cross(SS.GW.projUp);
Vector a = SK.GetEntity(c.ptA)->PointGetNum(); Vector a = SK.GetEntity(c.ptA)->PointGetNum();
Vector b = SK.GetEntity(c.ptB)->PointGetNum(); Vector b = SK.GetEntity(c.ptB)->PointGetNum();
@ -178,7 +178,7 @@ void Constraint::MenuConstrain(int id) {
c.disp.offset = Vector::From(0, 0, 0); c.disp.offset = Vector::From(0, 0, 0);
} }
if(id == GraphicsWindow::MNU_REF_DISTANCE) { if(id == Command::REF_DISTANCE) {
c.reference = true; c.reference = true;
} }
@ -188,25 +188,25 @@ void Constraint::MenuConstrain(int id) {
break; break;
} }
case GraphicsWindow::MNU_ON_ENTITY: case Command::ON_ENTITY:
if(gs.points == 2 && gs.n == 2) { if(gs.points == 2 && gs.n == 2) {
c.type = POINTS_COINCIDENT; c.type = Type::POINTS_COINCIDENT;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.ptB = gs.point[1]; c.ptB = gs.point[1];
} else if(gs.points == 1 && gs.workplanes == 1 && gs.n == 2) { } else if(gs.points == 1 && gs.workplanes == 1 && gs.n == 2) {
c.type = PT_IN_PLANE; c.type = Type::PT_IN_PLANE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
} else if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) { } else if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) {
c.type = PT_ON_LINE; c.type = Type::PT_ON_LINE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
} else if(gs.points == 1 && gs.circlesOrArcs == 1 && gs.n == 2) { } else if(gs.points == 1 && gs.circlesOrArcs == 1 && gs.n == 2) {
c.type = PT_ON_CIRCLE; c.type = Type::PT_ON_CIRCLE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
} else if(gs.points == 1 && gs.faces == 1 && gs.n == 2) { } else if(gs.points == 1 && gs.faces == 1 && gs.n == 2) {
c.type = PT_ON_FACE; c.type = Type::PT_ON_FACE;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityA = gs.face[0]; c.entityA = gs.face[0];
} else { } else {
@ -222,13 +222,13 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_EQUAL: case Command::EQUAL:
if(gs.lineSegments == 2 && gs.n == 2) { if(gs.lineSegments == 2 && gs.n == 2) {
c.type = EQUAL_LENGTH_LINES; c.type = Type::EQUAL_LENGTH_LINES;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
} else if(gs.lineSegments == 2 && gs.points == 2 && gs.n == 4) { } else if(gs.lineSegments == 2 && gs.points == 2 && gs.n == 4) {
c.type = EQ_PT_LN_DISTANCES; c.type = Type::EQ_PT_LN_DISTANCES;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
@ -236,35 +236,35 @@ void Constraint::MenuConstrain(int id) {
} else if(gs.lineSegments == 1 && gs.points == 2 && gs.n == 3) { } else if(gs.lineSegments == 1 && gs.points == 2 && gs.n == 3) {
// The same line segment for the distances, but different // The same line segment for the distances, but different
// points. // points.
c.type = EQ_PT_LN_DISTANCES; c.type = Type::EQ_PT_LN_DISTANCES;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.entityB = gs.entity[0]; c.entityB = gs.entity[0];
c.ptB = gs.point[1]; c.ptB = gs.point[1];
} else if(gs.lineSegments == 2 && gs.points == 1 && gs.n == 3) { } else if(gs.lineSegments == 2 && gs.points == 1 && gs.n == 3) {
c.type = EQ_LEN_PT_LINE_D; c.type = Type::EQ_LEN_PT_LINE_D;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
c.ptA = gs.point[0]; c.ptA = gs.point[0];
} else if(gs.vectors == 4 && gs.n == 4) { } else if(gs.vectors == 4 && gs.n == 4) {
c.type = EQUAL_ANGLE; c.type = Type::EQUAL_ANGLE;
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
c.entityB = gs.vector[1]; c.entityB = gs.vector[1];
c.entityC = gs.vector[2]; c.entityC = gs.vector[2];
c.entityD = gs.vector[3]; c.entityD = gs.vector[3];
} else if(gs.vectors == 3 && gs.n == 3) { } else if(gs.vectors == 3 && gs.n == 3) {
c.type = EQUAL_ANGLE; c.type = Type::EQUAL_ANGLE;
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
c.entityB = gs.vector[1]; c.entityB = gs.vector[1];
c.entityC = gs.vector[1]; c.entityC = gs.vector[1];
c.entityD = gs.vector[2]; c.entityD = gs.vector[2];
} else if(gs.circlesOrArcs == 2 && gs.n == 2) { } else if(gs.circlesOrArcs == 2 && gs.n == 2) {
c.type = EQUAL_RADIUS; c.type = Type::EQUAL_RADIUS;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
} else if(gs.arcs == 1 && gs.lineSegments == 1 && gs.n == 2) { } else if(gs.arcs == 1 && gs.lineSegments == 1 && gs.n == 2) {
c.type = EQUAL_LINE_ARC_LEN; c.type = Type::EQUAL_LINE_ARC_LEN;
if(SK.GetEntity(gs.entity[0])->type == Entity::ARC_OF_CIRCLE) { if(SK.GetEntity(gs.entity[0])->type == Entity::Type::ARC_OF_CIRCLE) {
c.entityA = gs.entity[1]; c.entityA = gs.entity[1];
c.entityB = gs.entity[0]; c.entityB = gs.entity[0];
} else { } else {
@ -290,7 +290,7 @@ void Constraint::MenuConstrain(int id) {
"(line segment length equals arc length)\n"); "(line segment length equals arc length)\n");
return; return;
} }
if(c.type == EQUAL_ANGLE) { if(c.type == Type::EQUAL_ANGLE) {
// Infer the nearest supplementary angle from the sketch. // Infer the nearest supplementary angle from the sketch.
Vector a1 = SK.GetEntity(c.entityA)->VectorGetNum(), Vector a1 = SK.GetEntity(c.entityA)->VectorGetNum(),
b1 = SK.GetEntity(c.entityB)->VectorGetNum(), b1 = SK.GetEntity(c.entityB)->VectorGetNum(),
@ -305,9 +305,9 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_RATIO: case Command::RATIO:
if(gs.lineSegments == 2 && gs.n == 2) { if(gs.lineSegments == 2 && gs.n == 2) {
c.type = LENGTH_RATIO; c.type = Type::LENGTH_RATIO;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
} else { } else {
@ -322,9 +322,9 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_DIFFERENCE: case Command::DIFFERENCE:
if(gs.lineSegments == 2 && gs.n == 2) { if(gs.lineSegments == 2 && gs.n == 2) {
c.type = LENGTH_DIFFERENCE; c.type = Type::LENGTH_DIFFERENCE;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.entityB = gs.entity[1]; c.entityB = gs.entity[1];
} else { } else {
@ -339,17 +339,17 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_AT_MIDPOINT: case Command::AT_MIDPOINT:
if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) { if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) {
c.type = AT_MIDPOINT; c.type = Type::AT_MIDPOINT;
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.ptA = gs.point[0]; c.ptA = gs.point[0];
// If a point is at-midpoint, then no reason to also constrain // If a point is at-midpoint, then no reason to also constrain
// it on-line; so auto-remove that. // it on-line; so auto-remove that.
DeleteAllConstraintsFor(PT_ON_LINE, c.entityA, c.ptA); DeleteAllConstraintsFor(Type::PT_ON_LINE, c.entityA, c.ptA);
} else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) {
c.type = AT_MIDPOINT; c.type = Type::AT_MIDPOINT;
int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0; int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0;
c.entityA = gs.entity[i]; c.entityA = gs.entity[i];
c.entityB = gs.entity[1-i]; c.entityB = gs.entity[1-i];
@ -365,7 +365,7 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_SYMMETRIC: case Command::SYMMETRIC:
if(gs.points == 2 && if(gs.points == 2 &&
((gs.workplanes == 1 && gs.n == 3) || ((gs.workplanes == 1 && gs.n == 3) ||
(gs.n == 2))) (gs.n == 2)))
@ -396,14 +396,14 @@ void Constraint::MenuConstrain(int id) {
c.ptA = l1->point[0]; c.ptA = l1->point[0];
c.ptB = l1->point[1]; c.ptB = l1->point[1];
c.entityA = l0->h; c.entityA = l0->h;
c.type = SYMMETRIC_LINE; c.type = Type::SYMMETRIC_LINE;
} else if(SS.GW.LockedInWorkplane() } else if(SS.GW.LockedInWorkplane()
&& gs.lineSegments == 1 && gs.points == 2 && gs.n == 3) && gs.lineSegments == 1 && gs.points == 2 && gs.n == 3)
{ {
c.ptA = gs.point[0]; c.ptA = gs.point[0];
c.ptB = gs.point[1]; c.ptB = gs.point[1];
c.entityA = gs.entity[0]; c.entityA = gs.entity[0];
c.type = SYMMETRIC_LINE; c.type = Type::SYMMETRIC_LINE;
} else { } else {
Error("Bad selection for symmetric constraint. This constraint " Error("Bad selection for symmetric constraint. This constraint "
"can apply to:\n\n" "can apply to:\n\n"
@ -415,7 +415,7 @@ void Constraint::MenuConstrain(int id) {
"(symmetric about workplane)\n"); "(symmetric about workplane)\n");
return; return;
} }
if(c.type != 0) { if(c.type != Type::UNKNOWN) {
// Already done, symmetry about a line segment in a workplane // Already done, symmetry about a line segment in a workplane
} else if(c.entityA.v == Entity::NO_ENTITY.v) { } else if(c.entityA.v == Entity::NO_ENTITY.v) {
// Horizontal / vertical symmetry, implicit symmetry plane // Horizontal / vertical symmetry, implicit symmetry plane
@ -431,28 +431,28 @@ void Constraint::MenuConstrain(int id) {
EntityBase *norm = SK.GetEntity(c.workplane)->Normal();; EntityBase *norm = SK.GetEntity(c.workplane)->Normal();;
Vector u = norm->NormalU(), v = norm->NormalV(); Vector u = norm->NormalU(), v = norm->NormalV();
if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) { if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) {
c.type = SYMMETRIC_HORIZ; c.type = Type::SYMMETRIC_HORIZ;
} else { } else {
c.type = SYMMETRIC_VERT; c.type = Type::SYMMETRIC_VERT;
} }
if(gs.lineSegments == 1) { if(gs.lineSegments == 1) {
// If this line segment is already constrained horiz or // If this line segment is already constrained horiz or
// vert, then auto-remove that redundant constraint. // vert, then auto-remove that redundant constraint.
DeleteAllConstraintsFor(HORIZONTAL, (gs.entity[0]), DeleteAllConstraintsFor(Type::HORIZONTAL, (gs.entity[0]),
Entity::NO_ENTITY); Entity::NO_ENTITY);
DeleteAllConstraintsFor(VERTICAL, (gs.entity[0]), DeleteAllConstraintsFor(Type::VERTICAL, (gs.entity[0]),
Entity::NO_ENTITY); Entity::NO_ENTITY);
} }
} else { } else {
// Symmetry with a symmetry plane specified explicitly. // Symmetry with a symmetry plane specified explicitly.
c.type = SYMMETRIC; c.type = Type::SYMMETRIC;
} }
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_VERTICAL: case Command::VERTICAL:
case GraphicsWindow::MNU_HORIZONTAL: { case Command::HORIZONTAL: {
hEntity ha, hb; hEntity ha, hb;
if(c.workplane.v == Entity::FREE_IN_3D.v) { if(c.workplane.v == Entity::FREE_IN_3D.v) {
Error("Select workplane before constraining horiz/vert."); Error("Select workplane before constraining horiz/vert.");
@ -473,18 +473,18 @@ void Constraint::MenuConstrain(int id) {
" * a line segment\n"); " * a line segment\n");
return; return;
} }
if(id == GraphicsWindow::MNU_HORIZONTAL) { if(id == Command::HORIZONTAL) {
c.type = HORIZONTAL; c.type = Type::HORIZONTAL;
} else { } else {
c.type = VERTICAL; c.type = Type::VERTICAL;
} }
AddConstraint(&c); AddConstraint(&c);
break; break;
} }
case GraphicsWindow::MNU_ORIENTED_SAME: { case Command::ORIENTED_SAME: {
if(gs.anyNormals == 2 && gs.n == 2) { if(gs.anyNormals == 2 && gs.n == 2) {
c.type = SAME_ORIENTATION; c.type = Type::SAME_ORIENTATION;
c.entityA = gs.anyNormal[0]; c.entityA = gs.anyNormal[0];
c.entityB = gs.anyNormal[1]; c.entityB = gs.anyNormal[1];
} else { } else {
@ -524,16 +524,16 @@ void Constraint::MenuConstrain(int id) {
break; break;
} }
case GraphicsWindow::MNU_OTHER_ANGLE: case Command::OTHER_ANGLE:
if(gs.constraints == 1 && gs.n == 0) { if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SK.GetConstraint(gs.constraint[0]); Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->type == ANGLE) { if(c->type == Type::ANGLE) {
SS.UndoRemember(); SS.UndoRemember();
c->other = !(c->other); c->other = !(c->other);
c->ModifyToSatisfy(); c->ModifyToSatisfy();
break; break;
} }
if(c->type == EQUAL_ANGLE) { if(c->type == Type::EQUAL_ANGLE) {
SS.UndoRemember(); SS.UndoRemember();
c->other = !(c->other); c->other = !(c->other);
SS.MarkGroupDirty(c->group); SS.MarkGroupDirty(c->group);
@ -544,10 +544,10 @@ void Constraint::MenuConstrain(int id) {
Error("Must select an angle constraint."); Error("Must select an angle constraint.");
return; return;
case GraphicsWindow::MNU_REFERENCE: case Command::REFERENCE:
if(gs.constraints == 1 && gs.n == 0) { if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SK.GetConstraint(gs.constraint[0]); Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->HasLabel() && c->type != COMMENT) { if(c->HasLabel() && c->type != Type::COMMENT) {
(c->reference) = !(c->reference); (c->reference) = !(c->reference);
SK.GetGroup(c->group)->clean = false; SK.GetGroup(c->group)->clean = false;
SS.GenerateAll(); SS.GenerateAll();
@ -557,10 +557,10 @@ void Constraint::MenuConstrain(int id) {
Error("Must select a constraint with associated label."); Error("Must select a constraint with associated label.");
return; return;
case GraphicsWindow::MNU_ANGLE: case Command::ANGLE:
case GraphicsWindow::MNU_REF_ANGLE: { case Command::REF_ANGLE: {
if(gs.vectors == 2 && gs.n == 2) { if(gs.vectors == 2 && gs.n == 2) {
c.type = ANGLE; c.type = Type::ANGLE;
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
c.entityB = gs.vector[1]; c.entityB = gs.vector[1];
c.valA = 0; c.valA = 0;
@ -575,8 +575,8 @@ void Constraint::MenuConstrain(int id) {
Entity *ea = SK.GetEntity(c.entityA), Entity *ea = SK.GetEntity(c.entityA),
*eb = SK.GetEntity(c.entityB); *eb = SK.GetEntity(c.entityB);
if(ea->type == Entity::LINE_SEGMENT && if(ea->type == Entity::Type::LINE_SEGMENT &&
eb->type == Entity::LINE_SEGMENT) eb->type == Entity::Type::LINE_SEGMENT)
{ {
Vector a0 = SK.GetEntity(ea->point[0])->PointGetNum(), Vector a0 = SK.GetEntity(ea->point[0])->PointGetNum(),
a1 = SK.GetEntity(ea->point[1])->PointGetNum(), a1 = SK.GetEntity(ea->point[1])->PointGetNum(),
@ -592,7 +592,7 @@ void Constraint::MenuConstrain(int id) {
} }
} }
if(id == GraphicsWindow::MNU_REF_ANGLE) { if(id == Command::REF_ANGLE) {
c.reference = true; c.reference = true;
} }
@ -601,15 +601,15 @@ void Constraint::MenuConstrain(int id) {
break; break;
} }
case GraphicsWindow::MNU_PARALLEL: case Command::PARALLEL:
if(gs.vectors == 2 && gs.n == 2) { if(gs.vectors == 2 && gs.n == 2) {
c.type = PARALLEL; c.type = Type::PARALLEL;
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
c.entityB = gs.vector[1]; c.entityB = gs.vector[1];
} else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) {
Entity *line = SK.GetEntity(gs.entity[0]); Entity *line = SK.GetEntity(gs.entity[0]);
Entity *arc = SK.GetEntity(gs.entity[1]); Entity *arc = SK.GetEntity(gs.entity[1]);
if(line->type == Entity::ARC_OF_CIRCLE) { if(line->type == Entity::Type::ARC_OF_CIRCLE) {
swap(line, arc); swap(line, arc);
} }
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
@ -627,13 +627,13 @@ void Constraint::MenuConstrain(int id) {
"On Point before constraining tangent."); "On Point before constraining tangent.");
return; return;
} }
c.type = ARC_LINE_TANGENT; c.type = Type::ARC_LINE_TANGENT;
c.entityA = arc->h; c.entityA = arc->h;
c.entityB = line->h; c.entityB = line->h;
} else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) { } else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) {
Entity *line = SK.GetEntity(gs.entity[0]); Entity *line = SK.GetEntity(gs.entity[0]);
Entity *cubic = SK.GetEntity(gs.entity[1]); Entity *cubic = SK.GetEntity(gs.entity[1]);
if(line->type == Entity::CUBIC) { if(line->type == Entity::Type::CUBIC) {
swap(line, cubic); swap(line, cubic);
} }
Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(),
@ -651,7 +651,7 @@ void Constraint::MenuConstrain(int id) {
"On Point before constraining tangent."); "On Point before constraining tangent.");
return; return;
} }
c.type = CUBIC_LINE_TANGENT; c.type = Type::CUBIC_LINE_TANGENT;
c.entityA = cubic->h; c.entityA = cubic->h;
c.entityB = line->h; c.entityB = line->h;
} else if(gs.cubics + gs.arcs == 2 && gs.n == 2) { } else if(gs.cubics + gs.arcs == 2 && gs.n == 2) {
@ -679,7 +679,7 @@ void Constraint::MenuConstrain(int id) {
"tangent."); "tangent.");
return; return;
} }
c.type = CURVE_CURVE_TANGENT; c.type = Type::CURVE_CURVE_TANGENT;
c.entityA = eA->h; c.entityA = eA->h;
c.entityB = eB->h; c.entityB = eB->h;
} else { } else {
@ -695,9 +695,9 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_PERPENDICULAR: case Command::PERPENDICULAR:
if(gs.vectors == 2 && gs.n == 2) { if(gs.vectors == 2 && gs.n == 2) {
c.type = PERPENDICULAR; c.type = Type::PERPENDICULAR;
c.entityA = gs.vector[0]; c.entityA = gs.vector[0];
c.entityB = gs.vector[1]; c.entityB = gs.vector[1];
} else { } else {
@ -711,9 +711,9 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_WHERE_DRAGGED: case Command::WHERE_DRAGGED:
if(gs.points == 1 && gs.n == 1) { if(gs.points == 1 && gs.n == 1) {
c.type = WHERE_DRAGGED; c.type = Type::WHERE_DRAGGED;
c.ptA = gs.point[0]; c.ptA = gs.point[0];
} else { } else {
Error("Bad selection for lock point where dragged constraint. " Error("Bad selection for lock point where dragged constraint. "
@ -724,8 +724,8 @@ void Constraint::MenuConstrain(int id) {
AddConstraint(&c); AddConstraint(&c);
break; break;
case GraphicsWindow::MNU_COMMENT: case Command::COMMENT:
SS.GW.pending.operation = GraphicsWindow::MNU_COMMENT; SS.GW.pending.operation = (int)Command::COMMENT;
SS.GW.pending.description = "click center of comment text"; SS.GW.pending.description = "click center of comment text";
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;

View File

@ -11,16 +11,16 @@ const hConstraint ConstraintBase::NO_CONSTRAINT = { 0 };
bool ConstraintBase::HasLabel() const { bool ConstraintBase::HasLabel() const {
switch(type) { switch(type) {
case PT_LINE_DISTANCE: case Type::PT_LINE_DISTANCE:
case PT_PLANE_DISTANCE: case Type::PT_PLANE_DISTANCE:
case PT_FACE_DISTANCE: case Type::PT_FACE_DISTANCE:
case PT_PT_DISTANCE: case Type::PT_PT_DISTANCE:
case PROJ_PT_DISTANCE: case Type::PROJ_PT_DISTANCE:
case DIAMETER: case Type::DIAMETER:
case LENGTH_RATIO: case Type::LENGTH_RATIO:
case LENGTH_DIFFERENCE: case Type::LENGTH_DIFFERENCE:
case ANGLE: case Type::ANGLE:
case COMMENT: case Type::COMMENT:
return true; return true;
default: default:
@ -167,7 +167,7 @@ ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane,
} }
void ConstraintBase::ModifyToSatisfy() { void ConstraintBase::ModifyToSatisfy() {
if(type == ANGLE) { if(type == Type::ANGLE) {
Vector a = SK.GetEntity(entityA)->VectorGetNum(); Vector a = SK.GetEntity(entityA)->VectorGetNum();
Vector b = SK.GetEntity(entityB)->VectorGetNum(); Vector b = SK.GetEntity(entityB)->VectorGetNum();
if(other) a = a.ScaledBy(-1); if(other) a = a.ScaledBy(-1);
@ -210,11 +210,11 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
Expr *exA = Expr::From(valA); Expr *exA = Expr::From(valA);
switch(type) { switch(type) {
case PT_PT_DISTANCE: case Type::PT_PT_DISTANCE:
AddEq(l, Distance(workplane, ptA, ptB)->Minus(exA), 0); AddEq(l, Distance(workplane, ptA, ptB)->Minus(exA), 0);
break; break;
case PROJ_PT_DISTANCE: { case Type::PROJ_PT_DISTANCE: {
ExprVector pA = SK.GetEntity(ptA)->PointGetExprs(), ExprVector pA = SK.GetEntity(ptA)->PointGetExprs(),
pB = SK.GetEntity(ptB)->PointGetExprs(), pB = SK.GetEntity(ptB)->PointGetExprs(),
dp = pB.Minus(pA); dp = pB.Minus(pA);
@ -226,18 +226,18 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case PT_LINE_DISTANCE: case Type::PT_LINE_DISTANCE:
AddEq(l, AddEq(l,
PointLineDistance(workplane, ptA, entityA)->Minus(exA), 0); PointLineDistance(workplane, ptA, entityA)->Minus(exA), 0);
break; break;
case PT_PLANE_DISTANCE: { case Type::PT_PLANE_DISTANCE: {
ExprVector pt = SK.GetEntity(ptA)->PointGetExprs(); ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
AddEq(l, (PointPlaneDistance(pt, entityA))->Minus(exA), 0); AddEq(l, (PointPlaneDistance(pt, entityA))->Minus(exA), 0);
break; break;
} }
case PT_FACE_DISTANCE: { case Type::PT_FACE_DISTANCE: {
ExprVector pt = SK.GetEntity(ptA)->PointGetExprs(); ExprVector pt = SK.GetEntity(ptA)->PointGetExprs();
EntityBase *f = SK.GetEntity(entityA); EntityBase *f = SK.GetEntity(entityA);
ExprVector p0 = f->FaceGetPointExprs(); ExprVector p0 = f->FaceGetPointExprs();
@ -246,7 +246,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case EQUAL_LENGTH_LINES: { case Type::EQUAL_LENGTH_LINES: {
EntityBase *a = SK.GetEntity(entityA); EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB); EntityBase *b = SK.GetEntity(entityB);
AddEq(l, Distance(workplane, a->point[0], a->point[1])->Minus( AddEq(l, Distance(workplane, a->point[0], a->point[1])->Minus(
@ -256,21 +256,21 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
// These work on distance squared, since the pt-line distances are // These work on distance squared, since the pt-line distances are
// signed, and we want the absolute value. // signed, and we want the absolute value.
case EQ_LEN_PT_LINE_D: { case Type::EQ_LEN_PT_LINE_D: {
EntityBase *forLen = SK.GetEntity(entityA); EntityBase *forLen = SK.GetEntity(entityA);
Expr *d1 = Distance(workplane, forLen->point[0], forLen->point[1]); Expr *d1 = Distance(workplane, forLen->point[0], forLen->point[1]);
Expr *d2 = PointLineDistance(workplane, ptA, entityB); Expr *d2 = PointLineDistance(workplane, ptA, entityB);
AddEq(l, (d1->Square())->Minus(d2->Square()), 0); AddEq(l, (d1->Square())->Minus(d2->Square()), 0);
break; break;
} }
case EQ_PT_LN_DISTANCES: { case Type::EQ_PT_LN_DISTANCES: {
Expr *d1 = PointLineDistance(workplane, ptA, entityA); Expr *d1 = PointLineDistance(workplane, ptA, entityA);
Expr *d2 = PointLineDistance(workplane, ptB, entityB); Expr *d2 = PointLineDistance(workplane, ptB, entityB);
AddEq(l, (d1->Square())->Minus(d2->Square()), 0); AddEq(l, (d1->Square())->Minus(d2->Square()), 0);
break; break;
} }
case LENGTH_RATIO: { case Type::LENGTH_RATIO: {
EntityBase *a = SK.GetEntity(entityA); EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB); EntityBase *b = SK.GetEntity(entityB);
Expr *la = Distance(workplane, a->point[0], a->point[1]); Expr *la = Distance(workplane, a->point[0], a->point[1]);
@ -279,7 +279,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case LENGTH_DIFFERENCE: { case Type::LENGTH_DIFFERENCE: {
EntityBase *a = SK.GetEntity(entityA); EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB); EntityBase *b = SK.GetEntity(entityB);
Expr *la = Distance(workplane, a->point[0], a->point[1]); Expr *la = Distance(workplane, a->point[0], a->point[1]);
@ -288,14 +288,14 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case DIAMETER: { case Type::DIAMETER: {
EntityBase *circle = SK.GetEntity(entityA); EntityBase *circle = SK.GetEntity(entityA);
Expr *r = circle->CircleGetRadiusExpr(); Expr *r = circle->CircleGetRadiusExpr();
AddEq(l, (r->Times(Expr::From(2)))->Minus(exA), 0); AddEq(l, (r->Times(Expr::From(2)))->Minus(exA), 0);
break; break;
} }
case EQUAL_RADIUS: { case Type::EQUAL_RADIUS: {
EntityBase *c1 = SK.GetEntity(entityA); EntityBase *c1 = SK.GetEntity(entityA);
EntityBase *c2 = SK.GetEntity(entityB); EntityBase *c2 = SK.GetEntity(entityB);
AddEq(l, (c1->CircleGetRadiusExpr())->Minus( AddEq(l, (c1->CircleGetRadiusExpr())->Minus(
@ -303,7 +303,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case EQUAL_LINE_ARC_LEN: { case Type::EQUAL_LINE_ARC_LEN: {
EntityBase *line = SK.GetEntity(entityA), EntityBase *line = SK.GetEntity(entityA),
*arc = SK.GetEntity(entityB); *arc = SK.GetEntity(entityB);
@ -346,7 +346,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case POINTS_COINCIDENT: { case Type::POINTS_COINCIDENT: {
EntityBase *a = SK.GetEntity(ptA); EntityBase *a = SK.GetEntity(ptA);
EntityBase *b = SK.GetEntity(ptB); EntityBase *b = SK.GetEntity(ptB);
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
@ -366,13 +366,13 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case PT_IN_PLANE: case Type::PT_IN_PLANE:
// This one works the same, whether projected or not. // This one works the same, whether projected or not.
AddEq(l, PointPlaneDistance( AddEq(l, PointPlaneDistance(
SK.GetEntity(ptA)->PointGetExprs(), entityA), 0); SK.GetEntity(ptA)->PointGetExprs(), entityA), 0);
break; break;
case PT_ON_FACE: { case Type::PT_ON_FACE: {
// a plane, n dot (p - p0) = 0 // a plane, n dot (p - p0) = 0
ExprVector p = SK.GetEntity(ptA)->PointGetExprs(); ExprVector p = SK.GetEntity(ptA)->PointGetExprs();
EntityBase *f = SK.GetEntity(entityA); EntityBase *f = SK.GetEntity(entityA);
@ -382,7 +382,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case PT_ON_LINE: case Type::PT_ON_LINE:
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
EntityBase *ln = SK.GetEntity(entityA); EntityBase *ln = SK.GetEntity(entityA);
EntityBase *a = SK.GetEntity(ln->point[0]); EntityBase *a = SK.GetEntity(ln->point[0]);
@ -414,7 +414,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
} }
break; break;
case PT_ON_CIRCLE: { case Type::PT_ON_CIRCLE: {
// This actually constrains the point to lie on the cylinder. // This actually constrains the point to lie on the cylinder.
EntityBase *circle = SK.GetEntity(entityA); EntityBase *circle = SK.GetEntity(entityA);
ExprVector center = SK.GetEntity(circle->point[0])->PointGetExprs(); ExprVector center = SK.GetEntity(circle->point[0])->PointGetExprs();
@ -433,7 +433,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case AT_MIDPOINT: case Type::AT_MIDPOINT:
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
EntityBase *ln = SK.GetEntity(entityA); EntityBase *ln = SK.GetEntity(entityA);
ExprVector a = SK.GetEntity(ln->point[0])->PointGetExprs(); ExprVector a = SK.GetEntity(ln->point[0])->PointGetExprs();
@ -472,7 +472,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
} }
break; break;
case SYMMETRIC: case Type::SYMMETRIC:
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
EntityBase *plane = SK.GetEntity(entityA); EntityBase *plane = SK.GetEntity(entityA);
EntityBase *ea = SK.GetEntity(ptA); EntityBase *ea = SK.GetEntity(ptA);
@ -523,8 +523,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
} }
break; break;
case SYMMETRIC_HORIZ: case Type::SYMMETRIC_HORIZ:
case SYMMETRIC_VERT: { case Type::SYMMETRIC_VERT: {
EntityBase *a = SK.GetEntity(ptA); EntityBase *a = SK.GetEntity(ptA);
EntityBase *b = SK.GetEntity(ptB); EntityBase *b = SK.GetEntity(ptB);
@ -532,7 +532,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
a->PointGetExprsInWorkplane(workplane, &au, &av); a->PointGetExprsInWorkplane(workplane, &au, &av);
b->PointGetExprsInWorkplane(workplane, &bu, &bv); b->PointGetExprsInWorkplane(workplane, &bu, &bv);
if(type == SYMMETRIC_HORIZ) { if(type == Type::SYMMETRIC_HORIZ) {
AddEq(l, av->Minus(bv), 0); AddEq(l, av->Minus(bv), 0);
AddEq(l, au->Plus(bu), 1); AddEq(l, au->Plus(bu), 1);
} else { } else {
@ -542,7 +542,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case SYMMETRIC_LINE: { case Type::SYMMETRIC_LINE: {
EntityBase *pa = SK.GetEntity(ptA); EntityBase *pa = SK.GetEntity(ptA);
EntityBase *pb = SK.GetEntity(ptB); EntityBase *pb = SK.GetEntity(ptB);
@ -575,8 +575,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case HORIZONTAL: case Type::HORIZONTAL:
case VERTICAL: { case Type::VERTICAL: {
hEntity ha, hb; hEntity ha, hb;
if(entityA.v) { if(entityA.v) {
EntityBase *e = SK.GetEntity(entityA); EntityBase *e = SK.GetEntity(entityA);
@ -593,11 +593,11 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
a->PointGetExprsInWorkplane(workplane, &au, &av); a->PointGetExprsInWorkplane(workplane, &au, &av);
b->PointGetExprsInWorkplane(workplane, &bu, &bv); b->PointGetExprsInWorkplane(workplane, &bu, &bv);
AddEq(l, (type == HORIZONTAL) ? av->Minus(bv) : au->Minus(bu), 0); AddEq(l, (type == Type::HORIZONTAL) ? av->Minus(bv) : au->Minus(bu), 0);
break; break;
} }
case SAME_ORIENTATION: { case Type::SAME_ORIENTATION: {
EntityBase *a = SK.GetEntity(entityA); EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB); EntityBase *b = SK.GetEntity(entityB);
if(b->group.v != group.v) { if(b->group.v != group.v) {
@ -624,8 +624,8 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case PERPENDICULAR: case Type::PERPENDICULAR:
case ANGLE: { case Type::ANGLE: {
EntityBase *a = SK.GetEntity(entityA); EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB); EntityBase *b = SK.GetEntity(entityB);
ExprVector ae = a->VectorGetExprs(); ExprVector ae = a->VectorGetExprs();
@ -633,7 +633,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
if(other) ae = ae.ScaledBy(Expr::From(-1)); if(other) ae = ae.ScaledBy(Expr::From(-1));
Expr *c = DirectionCosine(workplane, ae, be); Expr *c = DirectionCosine(workplane, ae, be);
if(type == ANGLE) { if(type == Type::ANGLE) {
// The direction cosine is equal to the cosine of the // The direction cosine is equal to the cosine of the
// specified angle // specified angle
Expr *rads = exA->Times(Expr::From(PI/180)), Expr *rads = exA->Times(Expr::From(PI/180)),
@ -653,7 +653,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case EQUAL_ANGLE: { case Type::EQUAL_ANGLE: {
EntityBase *a = SK.GetEntity(entityA); EntityBase *a = SK.GetEntity(entityA);
EntityBase *b = SK.GetEntity(entityB); EntityBase *b = SK.GetEntity(entityB);
EntityBase *c = SK.GetEntity(entityC); EntityBase *c = SK.GetEntity(entityC);
@ -672,7 +672,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case ARC_LINE_TANGENT: { case Type::ARC_LINE_TANGENT: {
EntityBase *arc = SK.GetEntity(entityA); EntityBase *arc = SK.GetEntity(entityA);
EntityBase *line = SK.GetEntity(entityB); EntityBase *line = SK.GetEntity(entityB);
@ -687,7 +687,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case CUBIC_LINE_TANGENT: { case Type::CUBIC_LINE_TANGENT: {
EntityBase *cubic = SK.GetEntity(entityA); EntityBase *cubic = SK.GetEntity(entityA);
EntityBase *line = SK.GetEntity(entityB); EntityBase *line = SK.GetEntity(entityB);
@ -711,7 +711,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case CURVE_CURVE_TANGENT: { case Type::CURVE_CURVE_TANGENT: {
bool parallel = true; bool parallel = true;
int i; int i;
ExprVector dir[2]; ExprVector dir[2];
@ -719,7 +719,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
EntityBase *e = SK.GetEntity((i == 0) ? entityA : entityB); EntityBase *e = SK.GetEntity((i == 0) ? entityA : entityB);
bool oth = (i == 0) ? other : other2; bool oth = (i == 0) ? other : other2;
if(e->type == Entity::ARC_OF_CIRCLE) { if(e->type == Entity::Type::ARC_OF_CIRCLE) {
ExprVector center, endpoint; ExprVector center, endpoint;
center = SK.GetEntity(e->point[0])->PointGetExprs(); center = SK.GetEntity(e->point[0])->PointGetExprs();
endpoint = endpoint =
@ -729,7 +729,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
// an endpoint; so that's normal to the tangent, not // an endpoint; so that's normal to the tangent, not
// parallel. // parallel.
parallel = !parallel; parallel = !parallel;
} else if(e->type == Entity::CUBIC) { } else if(e->type == Entity::Type::CUBIC) {
if(oth) { if(oth) {
dir[i] = e->CubicGetFinishTangentExprs(); dir[i] = e->CubicGetFinishTangentExprs();
} else { } else {
@ -749,7 +749,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case PARALLEL: { case Type::PARALLEL: {
EntityBase *ea = SK.GetEntity(entityA), *eb = SK.GetEntity(entityB); EntityBase *ea = SK.GetEntity(entityA), *eb = SK.GetEntity(entityB);
if(eb->group.v != group.v) { if(eb->group.v != group.v) {
swap(ea, eb); swap(ea, eb);
@ -768,7 +768,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case WHERE_DRAGGED: { case Type::WHERE_DRAGGED: {
EntityBase *ep = SK.GetEntity(ptA); EntityBase *ep = SK.GetEntity(ptA);
if(workplane.v == EntityBase::FREE_IN_3D.v) { if(workplane.v == EntityBase::FREE_IN_3D.v) {
ExprVector ev = ep->PointGetExprs(); ExprVector ev = ep->PointGetExprs();
@ -786,7 +786,7 @@ void ConstraintBase::GenerateReal(IdList<Equation,hEquation> *l) const {
break; break;
} }
case COMMENT: case Type::COMMENT:
break; break;
default: ssassert(false, "Unexpected constraint ID"); default: ssassert(false, "Unexpected constraint ID");

View File

@ -7,7 +7,7 @@
#include "solvespace.h" #include "solvespace.h"
void TextWindow::ScreenUnselectAll(int link, uint32_t v) { void TextWindow::ScreenUnselectAll(int link, uint32_t v) {
GraphicsWindow::MenuEdit(GraphicsWindow::MNU_UNSELECT_ALL); GraphicsWindow::MenuEdit(Command::UNSELECT_ALL);
} }
void TextWindow::ScreenEditTtfText(int link, uint32_t v) { void TextWindow::ScreenEditTtfText(int link, uint32_t v) {
@ -15,7 +15,7 @@ void TextWindow::ScreenEditTtfText(int link, uint32_t v) {
Request *r = SK.GetRequest(hr); Request *r = SK.GetRequest(hr);
SS.TW.ShowEditControl(10, r->str); SS.TW.ShowEditControl(10, r->str);
SS.TW.edit.meaning = EDIT_TTF_TEXT; SS.TW.edit.meaning = Edit::TTF_TEXT;
SS.TW.edit.request = hr; SS.TW.edit.request = hr;
} }
@ -29,7 +29,7 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
if(gs.entities != 1 || gs.n != 1) return; if(gs.entities != 1 || gs.n != 1) return;
Entity *e = SK.entity.FindByIdNoOops(gs.entity[0]); Entity *e = SK.entity.FindByIdNoOops(gs.entity[0]);
if(!e || e->type != Entity::TTF_TEXT || !e->h.isFromRequest()) return; if(!e || e->type != Entity::Type::TTF_TEXT || !e->h.isFromRequest()) return;
Request *r = SK.request.FindByIdNoOops(e->h.request()); Request *r = SK.request.FindByIdNoOops(e->h.request());
if(!r) return; if(!r) return;
@ -67,21 +67,21 @@ void TextWindow::DescribeSelection() {
#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) {
case Entity::POINT_IN_3D: case Entity::Type::POINT_IN_3D:
case Entity::POINT_IN_2D: case Entity::Type::POINT_IN_2D:
case Entity::POINT_N_TRANS: case Entity::Type::POINT_N_TRANS:
case Entity::POINT_N_ROT_TRANS: case Entity::Type::POINT_N_ROT_TRANS:
case Entity::POINT_N_COPY: case Entity::Type::POINT_N_COPY:
case Entity::POINT_N_ROT_AA: case Entity::Type::POINT_N_ROT_AA:
p = e->PointGetNum(); p = e->PointGetNum();
Printf(false, "%FtPOINT%E at " PT_AS_STR, COSTR(p)); Printf(false, "%FtPOINT%E at " PT_AS_STR, COSTR(p));
break; break;
case Entity::NORMAL_IN_3D: case Entity::Type::NORMAL_IN_3D:
case Entity::NORMAL_IN_2D: case Entity::Type::NORMAL_IN_2D:
case Entity::NORMAL_N_COPY: case Entity::Type::NORMAL_N_COPY:
case Entity::NORMAL_N_ROT: case Entity::Type::NORMAL_N_ROT:
case Entity::NORMAL_N_ROT_AA: { case Entity::Type::NORMAL_N_ROT_AA: {
Quaternion q = e->NormalGetNum(); Quaternion q = e->NormalGetNum();
p = q.RotationN(); p = q.RotationN();
Printf(false, "%FtNORMAL / COORDINATE SYSTEM%E"); Printf(false, "%FtNORMAL / COORDINATE SYSTEM%E");
@ -92,7 +92,7 @@ void TextWindow::DescribeSelection() {
Printf(false, " v = " PT_AS_NUM, CO(p)); Printf(false, " v = " PT_AS_NUM, CO(p));
break; break;
} }
case Entity::WORKPLANE: { case Entity::Type::WORKPLANE: {
p = SK.GetEntity(e->point[0])->PointGetNum(); p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(false, "%FtWORKPLANE%E"); Printf(false, "%FtWORKPLANE%E");
Printf(true, " origin = " PT_AS_STR, COSTR(p)); Printf(true, " origin = " PT_AS_STR, COSTR(p));
@ -101,7 +101,7 @@ void TextWindow::DescribeSelection() {
Printf(true, " normal = " PT_AS_NUM, CO(p)); Printf(true, " normal = " PT_AS_NUM, CO(p));
break; break;
} }
case Entity::LINE_SEGMENT: { case Entity::Type::LINE_SEGMENT: {
Vector p0 = SK.GetEntity(e->point[0])->PointGetNum(); Vector p0 = SK.GetEntity(e->point[0])->PointGetNum();
p = p0; p = p0;
Printf(false, "%FtLINE SEGMENT%E"); Printf(false, "%FtLINE SEGMENT%E");
@ -113,10 +113,10 @@ void TextWindow::DescribeSelection() {
SS.MmToString((p1.Minus(p0).Magnitude())).c_str()); SS.MmToString((p1.Minus(p0).Magnitude())).c_str());
break; break;
} }
case Entity::CUBIC_PERIODIC: case Entity::Type::CUBIC_PERIODIC:
case Entity::CUBIC: case Entity::Type::CUBIC:
int pts; int pts;
if(e->type == Entity::CUBIC_PERIODIC) { if(e->type == Entity::Type::CUBIC_PERIODIC) {
Printf(false, "%FtPERIODIC C2 CUBIC SPLINE%E"); Printf(false, "%FtPERIODIC C2 CUBIC SPLINE%E");
pts = (3 + e->extraPoints); pts = (3 + e->extraPoints);
} else if(e->extraPoints > 0) { } else if(e->extraPoints > 0) {
@ -132,7 +132,7 @@ void TextWindow::DescribeSelection() {
} }
break; break;
case Entity::ARC_OF_CIRCLE: { case Entity::Type::ARC_OF_CIRCLE: {
Printf(false, "%FtARC OF A CIRCLE%E"); Printf(false, "%FtARC OF A CIRCLE%E");
p = SK.GetEntity(e->point[0])->PointGetNum(); p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(true, " center = " PT_AS_STR, COSTR(p)); Printf(true, " center = " PT_AS_STR, COSTR(p));
@ -148,7 +148,7 @@ void TextWindow::DescribeSelection() {
Printf(false, " arc len = %Fi%s", SS.MmToString(dtheta*r).c_str()); Printf(false, " arc len = %Fi%s", SS.MmToString(dtheta*r).c_str());
break; break;
} }
case Entity::CIRCLE: { case Entity::Type::CIRCLE: {
Printf(false, "%FtCIRCLE%E"); Printf(false, "%FtCIRCLE%E");
p = SK.GetEntity(e->point[0])->PointGetNum(); p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(true, " center = " PT_AS_STR, COSTR(p)); Printf(true, " center = " PT_AS_STR, COSTR(p));
@ -157,11 +157,11 @@ void TextWindow::DescribeSelection() {
Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str()); Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str());
break; break;
} }
case Entity::FACE_NORMAL_PT: case Entity::Type::FACE_NORMAL_PT:
case Entity::FACE_XPROD: case Entity::Type::FACE_XPROD:
case Entity::FACE_N_ROT_TRANS: case Entity::Type::FACE_N_ROT_TRANS:
case Entity::FACE_N_ROT_AA: case Entity::Type::FACE_N_ROT_AA:
case Entity::FACE_N_TRANS: case Entity::Type::FACE_N_TRANS:
Printf(false, "%FtPLANE FACE%E"); Printf(false, "%FtPLANE FACE%E");
p = e->FaceGetNormalNum(); p = e->FaceGetNormalNum();
Printf(true, " normal = " PT_AS_NUM, CO(p)); Printf(true, " normal = " PT_AS_NUM, CO(p));
@ -169,7 +169,7 @@ void TextWindow::DescribeSelection() {
Printf(false, " thru = " PT_AS_STR, COSTR(p)); Printf(false, " thru = " PT_AS_STR, COSTR(p));
break; break;
case Entity::TTF_TEXT: { case Entity::Type::TTF_TEXT: {
Printf(false, "%FtTRUETYPE FONT TEXT%E"); Printf(false, "%FtTRUETYPE FONT TEXT%E");
Printf(true, " font = '%Fi%s%E'", e->font.c_str()); Printf(true, " font = '%Fi%s%E'", e->font.c_str());
if(e->h.isFromRequest()) { if(e->h.isFromRequest()) {
@ -231,9 +231,9 @@ void TextWindow::DescribeSelection() {
Printf(true, " d = %Fi%s", SS.MmToString(d).c_str()); Printf(true, " d = %Fi%s", SS.MmToString(d).c_str());
} else if(gs.n == 2 && gs.points == 1 && gs.circlesOrArcs == 1) { } else if(gs.n == 2 && gs.points == 1 && gs.circlesOrArcs == 1) {
Entity *ec = SK.GetEntity(gs.entity[0]); Entity *ec = SK.GetEntity(gs.entity[0]);
if(ec->type == Entity::CIRCLE) { if(ec->type == Entity::Type::CIRCLE) {
Printf(false, "%FtPOINT AND A CIRCLE"); Printf(false, "%FtPOINT AND A CIRCLE");
} else if(ec->type == Entity::ARC_OF_CIRCLE) { } else if(ec->type == Entity::Type::ARC_OF_CIRCLE) {
Printf(false, "%FtPOINT AND AN ARC"); Printf(false, "%FtPOINT AND AN ARC");
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
Vector p = SK.GetEntity(gs.point[0])->PointGetNum(); Vector p = SK.GetEntity(gs.point[0])->PointGetNum();
@ -321,7 +321,7 @@ void TextWindow::DescribeSelection() {
} else if(gs.n == 0 && gs.constraints == 1) { } else if(gs.n == 0 && gs.constraints == 1) {
Constraint *c = SK.GetConstraint(gs.constraint[0]); Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->type == Constraint::DIAMETER) { if(c->type == Constraint::Type::DIAMETER) {
Printf(false, "%FtDIAMETER CONSTRAINT"); Printf(false, "%FtDIAMETER CONSTRAINT");
Printf(true, " %Fd%f%D%Ll%s show as radius", Printf(true, " %Fd%f%D%Ll%s show as radius",
@ -336,7 +336,7 @@ void TextWindow::DescribeSelection() {
Printf(false, "%FtSELECTED:%E %d item%s", n, n == 1 ? "" : "s"); Printf(false, "%FtSELECTED:%E %d item%s", n, n == 1 ? "" : "s");
} }
if(shown.screen == SCREEN_STYLE_INFO && if(shown.screen == Screen::STYLE_INFO &&
shown.style.v >= Style::FIRST_CUSTOM && gs.stylables > 0) shown.style.v >= Style::FIRST_CUSTOM && gs.stylables > 0)
{ {
// If we are showing a screen for a particular style, then offer the // If we are showing a screen for a particular style, then offer the
@ -358,7 +358,7 @@ void TextWindow::DescribeSelection() {
} }
for(i = 0; i < gs.constraints; i++) { for(i = 0; i < gs.constraints; i++) {
Constraint *c = SK.GetConstraint(gs.constraint[i]); Constraint *c = SK.GetConstraint(gs.constraint[i]);
if(c->type == Constraint::COMMENT && c->disp.style.v != 0) { if(c->type == Constraint::Type::COMMENT && c->disp.style.v != 0) {
styleAssigned = true; styleAssigned = true;
} }
} }
@ -371,7 +371,7 @@ void TextWindow::DescribeSelection() {
Printf(true, "%Fl%f%Ll(unselect all)%E", &TextWindow::ScreenUnselectAll); Printf(true, "%Fl%f%Ll(unselect all)%E", &TextWindow::ScreenUnselectAll);
} }
void TextWindow::GoToScreen(int screen) { void TextWindow::GoToScreen(Screen screen) {
shown.screen = screen; shown.screen = screen;
} }

View File

@ -261,17 +261,17 @@ void GraphicsWindow::GroupSelection() {
// And some aux counts too // And some aux counts too
switch(e->type) { switch(e->type) {
case Entity::WORKPLANE: (gs.workplanes)++; break; case Entity::Type::WORKPLANE: (gs.workplanes)++; break;
case Entity::LINE_SEGMENT: (gs.lineSegments)++; break; case Entity::Type::LINE_SEGMENT: (gs.lineSegments)++; break;
case Entity::CUBIC: (gs.cubics)++; break; case Entity::Type::CUBIC: (gs.cubics)++; break;
case Entity::CUBIC_PERIODIC: (gs.periodicCubics)++; break; case Entity::Type::CUBIC_PERIODIC: (gs.periodicCubics)++; break;
case Entity::ARC_OF_CIRCLE: case Entity::Type::ARC_OF_CIRCLE:
(gs.circlesOrArcs)++; (gs.circlesOrArcs)++;
(gs.arcs)++; (gs.arcs)++;
break; break;
case Entity::CIRCLE: (gs.circlesOrArcs)++; break; case Entity::Type::CIRCLE: (gs.circlesOrArcs)++; break;
} }
} }
if(s->constraint.v) { if(s->constraint.v) {
@ -314,7 +314,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
if(!e->IsPoint()) continue; if(!e->IsPoint()) continue;
if(!e->h.isFromRequest()) continue; if(!e->h.isFromRequest()) continue;
Request *r = SK.GetRequest(e->h.request()); Request *r = SK.GetRequest(e->h.request());
if(r->type != Request::CUBIC) continue; if(r->type != Request::Type::CUBIC) continue;
if(r->extraPoints < 2) continue; if(r->extraPoints < 2) continue;
if(e->h.v != r->h.entity(1).v) continue; if(e->h.v != r->h.entity(1).v) continue;
} }
@ -681,7 +681,7 @@ nogrid:;
// Draw the "pending" constraint, i.e. a constraint that would be // Draw the "pending" constraint, i.e. a constraint that would be
// placed on a line that is almost horizontal or vertical // placed on a line that is almost horizontal or vertical
if(SS.GW.pending.operation == DRAGGING_NEW_LINE_POINT) { if(SS.GW.pending.operation == DRAGGING_NEW_LINE_POINT) {
if(SS.GW.pending.suggestion != GraphicsWindow::SUGGESTED_NONE) { if(SS.GW.pending.suggestion != Constraint::Type::UNKNOWN) {
Constraint c = {}; Constraint c = {};
c.group = SS.GW.activeGroup; c.group = SS.GW.activeGroup;
c.workplane = SS.GW.ActiveWorkplane(); c.workplane = SS.GW.ActiveWorkplane();

View File

@ -41,17 +41,17 @@ static void LineCallback(void *fndata, Vector a, Vector b)
std::string Constraint::Label() const { std::string Constraint::Label() const {
std::string result; std::string result;
if(type == ANGLE) { if(type == Type::ANGLE) {
if(valA == floor(valA)) { if(valA == floor(valA)) {
result = ssprintf("%.0f°", valA); result = ssprintf("%.0f°", valA);
} else { } else {
result = ssprintf("%.2f°", valA); result = ssprintf("%.2f°", valA);
} }
} else if(type == LENGTH_RATIO) { } else if(type == Type::LENGTH_RATIO) {
result = ssprintf("%.3f:1", valA); result = ssprintf("%.3f:1", valA);
} else if(type == COMMENT) { } else if(type == Type::COMMENT) {
result = comment; result = comment;
} else if(type == DIAMETER) { } else if(type == Type::DIAMETER) {
if(!other) { if(!other) {
result = "" + SS.MmToString(valA); result = "" + SS.MmToString(valA);
} else { } else {
@ -78,7 +78,7 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
// By default, the reference is from the center; but the style could // By default, the reference is from the center; but the style could
// specify otherwise if one is present, and it could also specify a // specify otherwise if one is present, and it could also specify a
// rotation. // rotation.
if(type == COMMENT && disp.style.v) { if(type == Type::COMMENT && disp.style.v) {
Style *st = Style::Get(disp.style); Style *st = Style::Get(disp.style);
// rotation first // rotation first
double rads = st->textAngle*PI/180; double rads = st->textAngle*PI/180;
@ -87,11 +87,11 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
gr = pr.ScaledBy( c).Plus(pu.ScaledBy(s)); gr = pr.ScaledBy( c).Plus(pu.ScaledBy(s));
gu = pr.ScaledBy(-s).Plus(pu.ScaledBy(c)); gu = pr.ScaledBy(-s).Plus(pu.ScaledBy(c));
// then origin // then origin
int o = st->textOrigin; uint32_t o = (uint32_t)st->textOrigin;
if(o & Style::ORIGIN_LEFT) ref = ref.Plus(gr.WithMagnitude(swidth/2)); if(o & (uint32_t)Style::TextOrigin::LEFT) ref = ref.Plus(gr.WithMagnitude(swidth/2));
if(o & Style::ORIGIN_RIGHT) ref = ref.Minus(gr.WithMagnitude(swidth/2)); if(o & (uint32_t)Style::TextOrigin::RIGHT) ref = ref.Minus(gr.WithMagnitude(swidth/2));
if(o & Style::ORIGIN_BOT) ref = ref.Plus(gu.WithMagnitude(sheight/2)); if(o & (uint32_t)Style::TextOrigin::BOT) ref = ref.Plus(gu.WithMagnitude(sheight/2));
if(o & Style::ORIGIN_TOP) ref = ref.Minus(gu.WithMagnitude(sheight/2)); if(o & (uint32_t)Style::TextOrigin::TOP) ref = ref.Minus(gu.WithMagnitude(sheight/2));
} }
if(labelPos) { if(labelPos) {
@ -298,9 +298,9 @@ void Constraint::DoEqualRadiusTicks(hEntity he, Vector *refp) {
Vector u = q.RotationU(), v = q.RotationV(); Vector u = q.RotationU(), v = q.RotationV();
double theta; double theta;
if(circ->type == Entity::CIRCLE) { if(circ->type == Entity::Type::CIRCLE) {
theta = PI/2; theta = PI/2;
} else if(circ->type == Entity::ARC_OF_CIRCLE) { } else if(circ->type == Entity::Type::ARC_OF_CIRCLE) {
double thetaa, thetab, dtheta; double thetaa, thetab, dtheta;
circ->ArcGetAngles(&thetaa, &thetab, &dtheta); circ->ArcGetAngles(&thetaa, &thetab, &dtheta);
theta = thetaa + dtheta/2; theta = thetaa + dtheta/2;
@ -473,7 +473,7 @@ bool Constraint::IsVisible() const {
if(!(g->visible)) return false; if(!(g->visible)) return false;
// And likewise if the group is not the active group; except for comments // And likewise if the group is not the active group; except for comments
// with an assigned style. // with an assigned style.
if(g->h.v != SS.GW.activeGroup.v && !(type == COMMENT && disp.style.v)) { if(g->h.v != SS.GW.activeGroup.v && !(type == Type::COMMENT && disp.style.v)) {
return false; return false;
} }
if(disp.style.v) { if(disp.style.v) {
@ -522,7 +522,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
Vector gn = (gr.Cross(gu)).WithMagnitude(1/SS.GW.scale); Vector gn = (gr.Cross(gu)).WithMagnitude(1/SS.GW.scale);
switch(type) { switch(type) {
case PT_PT_DISTANCE: { case Type::PT_PT_DISTANCE: {
Vector ap = SK.GetEntity(ptA)->PointGetNum(); Vector ap = SK.GetEntity(ptA)->PointGetNum();
Vector bp = SK.GetEntity(ptB)->PointGetNum(); Vector bp = SK.GetEntity(ptB)->PointGetNum();
@ -539,7 +539,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case PROJ_PT_DISTANCE: { case Type::PROJ_PT_DISTANCE: {
Vector ap = SK.GetEntity(ptA)->PointGetNum(), Vector ap = SK.GetEntity(ptA)->PointGetNum(),
bp = SK.GetEntity(ptB)->PointGetNum(), bp = SK.GetEntity(ptB)->PointGetNum(),
dp = (bp.Minus(ap)), dp = (bp.Minus(ap)),
@ -559,12 +559,12 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case PT_FACE_DISTANCE: case Type::PT_FACE_DISTANCE:
case PT_PLANE_DISTANCE: { case Type::PT_PLANE_DISTANCE: {
Vector pt = SK.GetEntity(ptA)->PointGetNum(); Vector pt = SK.GetEntity(ptA)->PointGetNum();
Entity *enta = SK.GetEntity(entityA); Entity *enta = SK.GetEntity(entityA);
Vector n, p; Vector n, p;
if(type == PT_PLANE_DISTANCE) { if(type == Type::PT_PLANE_DISTANCE) {
n = enta->Normal()->NormalN(); n = enta->Normal()->NormalN();
p = enta->WorkplaneGetOffset(); p = enta->WorkplaneGetOffset();
} else { } else {
@ -586,7 +586,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case PT_LINE_DISTANCE: { case Type::PT_LINE_DISTANCE: {
Vector pt = SK.GetEntity(ptA)->PointGetNum(); Vector pt = SK.GetEntity(ptA)->PointGetNum();
Entity *line = SK.GetEntity(entityA); Entity *line = SK.GetEntity(entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum(); Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
@ -638,7 +638,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case DIAMETER: { case Type::DIAMETER: {
Entity *circle = SK.GetEntity(entityA); Entity *circle = SK.GetEntity(entityA);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum(); Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
@ -660,7 +660,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case POINTS_COINCIDENT: { case Type::POINTS_COINCIDENT: {
if(!dogd.drawing) { if(!dogd.drawing) {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum(); Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
@ -707,19 +707,19 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case PT_ON_CIRCLE: case Type::PT_ON_CIRCLE:
case PT_ON_LINE: case Type::PT_ON_LINE:
case PT_ON_FACE: case Type::PT_ON_FACE:
case PT_IN_PLANE: { case Type::PT_IN_PLANE: {
double s = 8/SS.GW.scale; double s = 8/SS.GW.scale;
Vector p = SK.GetEntity(ptA)->PointGetNum(); Vector p = SK.GetEntity(ptA)->PointGetNum();
if(refps) refps[0] = refps[1] = p; if(refps) refps[0] = refps[1] = p;
Vector r, d; Vector r, d;
if(type == PT_ON_FACE) { if(type == Type::PT_ON_FACE) {
Vector n = SK.GetEntity(entityA)->FaceGetNormalNum(); Vector n = SK.GetEntity(entityA)->FaceGetNormalNum();
r = n.Normal(0); r = n.Normal(0);
d = n.Normal(1); d = n.Normal(1);
} else if(type == PT_IN_PLANE) { } else if(type == Type::PT_IN_PLANE) {
EntityBase *n = SK.GetEntity(entityA)->Normal(); EntityBase *n = SK.GetEntity(entityA)->Normal();
r = n->NormalU(); r = n->NormalU();
d = n->NormalV(); d = n->NormalV();
@ -736,7 +736,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case WHERE_DRAGGED: { case Type::WHERE_DRAGGED: {
Vector p = SK.GetEntity(ptA)->PointGetNum(); Vector p = SK.GetEntity(ptA)->PointGetNum();
if(refps) refps[0] = refps[1] = p; if(refps) refps[0] = refps[1] = p;
Vector u = p.Plus(gu.WithMagnitude(8/SS.GW.scale)).Plus( Vector u = p.Plus(gu.WithMagnitude(8/SS.GW.scale)).Plus(
@ -756,7 +756,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case SAME_ORIENTATION: { case Type::SAME_ORIENTATION: {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
Quaternion q = e->NormalGetNum(); Quaternion q = e->NormalGetNum();
@ -772,7 +772,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case EQUAL_ANGLE: { case Type::EQUAL_ANGLE: {
Vector ref; Vector ref;
Entity *a = SK.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
@ -803,7 +803,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case ANGLE: { case Type::ANGLE: {
Entity *a = SK.GetEntity(entityA); Entity *a = SK.GetEntity(entityA);
Entity *b = SK.GetEntity(entityB); Entity *b = SK.GetEntity(entityB);
@ -823,7 +823,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case PERPENDICULAR: { case Type::PERPENDICULAR: {
Vector u = Vector::From(0, 0, 0), v = Vector::From(0, 0, 0); Vector u = Vector::From(0, 0, 0), v = Vector::From(0, 0, 0);
Vector rn, ru; Vector rn, ru;
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
@ -862,12 +862,12 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case CURVE_CURVE_TANGENT: case Type::CURVE_CURVE_TANGENT:
case CUBIC_LINE_TANGENT: case Type::CUBIC_LINE_TANGENT:
case ARC_LINE_TANGENT: { case Type::ARC_LINE_TANGENT: {
Vector textAt, u, v; Vector textAt, u, v;
if(type == ARC_LINE_TANGENT) { if(type == Type::ARC_LINE_TANGENT) {
Entity *arc = SK.GetEntity(entityA); Entity *arc = SK.GetEntity(entityA);
Entity *norm = SK.GetEntity(arc->normal); Entity *norm = SK.GetEntity(arc->normal);
Vector c = SK.GetEntity(arc->point[0])->PointGetNum(); Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
@ -877,7 +877,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale)); textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
u = norm->NormalU(); u = norm->NormalU();
v = norm->NormalV(); v = norm->NormalV();
} else if(type == CUBIC_LINE_TANGENT) { } else if(type == Type::CUBIC_LINE_TANGENT) {
Vector n; Vector n;
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
u = gr; u = gr;
@ -908,7 +908,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
// or an arc. // or an arc.
if(other) { if(other) {
textAt = eA->EndpointFinish(); textAt = eA->EndpointFinish();
if(eA->type == Entity::CUBIC) { if(eA->type == Entity::Type::CUBIC) {
dir = eA->CubicGetFinishTangentNum(); dir = eA->CubicGetFinishTangentNum();
} else { } else {
dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus( dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus(
@ -917,7 +917,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
} }
} else { } else {
textAt = eA->EndpointStart(); textAt = eA->EndpointStart();
if(eA->type == Entity::CUBIC) { if(eA->type == Entity::Type::CUBIC) {
dir = eA->CubicGetStartTangentNum(); dir = eA->CubicGetStartTangentNum();
} else { } else {
dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus( dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus(
@ -940,7 +940,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case PARALLEL: { case Type::PARALLEL: {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
Vector n = e->VectorGetNum(); Vector n = e->VectorGetNum();
@ -955,7 +955,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case EQUAL_RADIUS: { case Type::EQUAL_RADIUS: {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Vector ref; Vector ref;
DoEqualRadiusTicks(i == 0 ? entityA : entityB, &ref); DoEqualRadiusTicks(i == 0 ? entityA : entityB, &ref);
@ -964,7 +964,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case EQUAL_LINE_ARC_LEN: { case Type::EQUAL_LINE_ARC_LEN: {
Entity *line = SK.GetEntity(entityA); Entity *line = SK.GetEntity(entityA);
Vector refa, refb; Vector refa, refb;
DoEqualLenTicks( DoEqualLenTicks(
@ -979,9 +979,9 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case LENGTH_RATIO: case Type::LENGTH_RATIO:
case LENGTH_DIFFERENCE: case Type::LENGTH_DIFFERENCE:
case EQUAL_LENGTH_LINES: { case Type::EQUAL_LENGTH_LINES: {
Vector a, b = Vector::From(0, 0, 0); Vector a, b = Vector::From(0, 0, 0);
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
@ -997,14 +997,14 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
DoEqualLenTicks(a, b, gn, &ref); DoEqualLenTicks(a, b, gn, &ref);
if(refps) refps[i] = ref; if(refps) refps[i] = ref;
} }
if((type == LENGTH_RATIO) || (type == LENGTH_DIFFERENCE)) { if((type == Type::LENGTH_RATIO) || (type == Type::LENGTH_DIFFERENCE)) {
Vector ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset); Vector ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset);
DoLabel(ref, labelPos, gr, gu); DoLabel(ref, labelPos, gr, gu);
} }
break; break;
} }
case EQ_LEN_PT_LINE_D: { case Type::EQ_LEN_PT_LINE_D: {
Entity *forLen = SK.GetEntity(entityA); Entity *forLen = SK.GetEntity(entityA);
Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(), Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(),
b = SK.GetEntity(forLen->point[1])->PointGetNum(); b = SK.GetEntity(forLen->point[1])->PointGetNum();
@ -1034,7 +1034,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
break; break;
} }
case EQ_PT_LN_DISTANCES: { case Type::EQ_PT_LN_DISTANCES: {
for(int i = 0; i < 2; i++) { for(int i = 0; i < 2; i++) {
Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB); Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB);
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(), Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
@ -1059,14 +1059,14 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
} }
{ {
case SYMMETRIC: case Type::SYMMETRIC:
Vector n; Vector n;
n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s; n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s;
case SYMMETRIC_HORIZ: case Type::SYMMETRIC_HORIZ:
n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s; n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s;
case SYMMETRIC_VERT: case Type::SYMMETRIC_VERT:
n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s; n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s;
case SYMMETRIC_LINE: { case Type::SYMMETRIC_LINE: {
Entity *ln = SK.GetEntity(entityA); Entity *ln = SK.GetEntity(entityA);
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(), Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
lb = SK.GetEntity(ln->point[1])->PointGetNum(); lb = SK.GetEntity(ln->point[1])->PointGetNum();
@ -1102,9 +1102,9 @@ s:
break; break;
} }
case AT_MIDPOINT: case Type::AT_MIDPOINT:
case HORIZONTAL: case Type::HORIZONTAL:
case VERTICAL: case Type::VERTICAL:
if(entityA.v) { if(entityA.v) {
Vector r, u, n; Vector r, u, n;
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
@ -1123,12 +1123,12 @@ s:
offset = offset.WithMagnitude(13/SS.GW.scale); offset = offset.WithMagnitude(13/SS.GW.scale);
// Draw midpoint constraint on other side of line, so that // Draw midpoint constraint on other side of line, so that
// a line can be midpoint and horizontal at same time. // a line can be midpoint and horizontal at same time.
if(type == AT_MIDPOINT) offset = offset.ScaledBy(-1); if(type == Type::AT_MIDPOINT) offset = offset.ScaledBy(-1);
if(dogd.drawing) { if(dogd.drawing) {
const char *s = (type == HORIZONTAL) ? "H" : ( const char *s = (type == Type::HORIZONTAL) ? "H" : (
(type == VERTICAL) ? "V" : ( (type == Type::VERTICAL) ? "V" : (
(type == AT_MIDPOINT) ? "M" : NULL)); (type == Type::AT_MIDPOINT) ? "M" : NULL));
ssglWriteTextRefCenter(s, Style::DefaultTextHeight(), ssglWriteTextRefCenter(s, Style::DefaultTextHeight(),
m.Plus(offset), r, u, LineCallback, (void *)this); m.Plus(offset), r, u, LineCallback, (void *)this);
@ -1150,7 +1150,7 @@ s:
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
Vector o = (i == 0) ? a : b; Vector o = (i == 0) ? a : b;
Vector oo = (i == 0) ? a.Minus(b) : b.Minus(a); Vector oo = (i == 0) ? a.Minus(b) : b.Minus(a);
Vector d = (type == HORIZONTAL) ? cu : cv; Vector d = (type == Type::HORIZONTAL) ? cu : cv;
if(oo.Dot(d) < 0) d = d.ScaledBy(-1); if(oo.Dot(d) < 0) d = d.ScaledBy(-1);
Vector dp = cn.Cross(d); Vector dp = cn.Cross(d);
@ -1175,7 +1175,7 @@ s:
} }
break; break;
case COMMENT: { case Type::COMMENT: {
if(dogd.drawing && disp.style.v) { if(dogd.drawing && disp.style.v) {
ssglLineWidth(Style::Width(disp.style)); ssglLineWidth(Style::Width(disp.style));
ssglColorRGB(Style::Color(disp.style)); ssglColorRGB(Style::Color(disp.style));
@ -1246,7 +1246,7 @@ void Constraint::GetEdges(SEdgeList *sel) {
} }
bool Constraint::IsStylable() const { bool Constraint::IsStylable() const {
if(type == COMMENT) return true; if(type == Type::COMMENT) return true;
return false; return false;
} }
@ -1257,16 +1257,16 @@ hStyle Constraint::GetStyle() const {
bool Constraint::HasLabel() const { bool Constraint::HasLabel() const {
switch(type) { switch(type) {
case COMMENT: case Type::COMMENT:
case PT_PT_DISTANCE: case Type::PT_PT_DISTANCE:
case PT_PLANE_DISTANCE: case Type::PT_PLANE_DISTANCE:
case PT_LINE_DISTANCE: case Type::PT_LINE_DISTANCE:
case PT_FACE_DISTANCE: case Type::PT_FACE_DISTANCE:
case PROJ_PT_DISTANCE: case Type::PROJ_PT_DISTANCE:
case LENGTH_RATIO: case Type::LENGTH_RATIO:
case LENGTH_DIFFERENCE: case Type::LENGTH_DIFFERENCE:
case DIAMETER: case Type::DIAMETER:
case ANGLE: case Type::ANGLE:
return true; return true;
default: default:

View File

@ -62,13 +62,13 @@ void Entity::DrawAll(bool drawAsHidden) {
// then we draw big colored squares over the points that are // then we draw big colored squares over the points that are
// free to move. // free to move.
bool free = false; bool free = false;
if(e->type == POINT_IN_3D) { if(e->type == Type::POINT_IN_3D) {
Param *px = SK.GetParam(e->param[0]), Param *px = SK.GetParam(e->param[0]),
*py = SK.GetParam(e->param[1]), *py = SK.GetParam(e->param[1]),
*pz = SK.GetParam(e->param[2]); *pz = SK.GetParam(e->param[2]);
free = (px->free) || (py->free) || (pz->free); free = (px->free) || (py->free) || (pz->free);
} else if(e->type == POINT_IN_2D) { } else if(e->type == Type::POINT_IN_2D) {
Param *pu = SK.GetParam(e->param[0]), Param *pu = SK.GetParam(e->param[0]),
*pv = SK.GetParam(e->param[1]); *pv = SK.GetParam(e->param[1]);
@ -197,27 +197,27 @@ double Entity::GetDistance(Point2d mp) {
Vector Entity::GetReferencePos() { Vector Entity::GetReferencePos() {
switch(type) { switch(type) {
case POINT_N_COPY: case Type::POINT_N_COPY:
case POINT_N_TRANS: case Type::POINT_N_TRANS:
case POINT_N_ROT_TRANS: case Type::POINT_N_ROT_TRANS:
case POINT_N_ROT_AA: case Type::POINT_N_ROT_AA:
case POINT_IN_3D: case Type::POINT_IN_3D:
case POINT_IN_2D: case Type::POINT_IN_2D:
return PointGetNum(); return PointGetNum();
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case CIRCLE: case Type::CIRCLE:
case ARC_OF_CIRCLE: case Type::ARC_OF_CIRCLE:
case CUBIC: case Type::CUBIC:
case CUBIC_PERIODIC: case Type::CUBIC_PERIODIC:
case TTF_TEXT: case Type::TTF_TEXT:
return SK.GetEntity(point[0])->PointGetNum(); return SK.GetEntity(point[0])->PointGetNum();
case LINE_SEGMENT: { case Type::LINE_SEGMENT: {
Vector a = SK.GetEntity(point[0])->PointGetNum(), Vector a = SK.GetEntity(point[0])->PointGetNum(),
b = SK.GetEntity(point[1])->PointGetNum(); b = SK.GetEntity(point[1])->PointGetNum();
return b.Plus(a.Minus(b).ScaledBy(0.5)); return b.Plus(a.Minus(b).ScaledBy(0.5));
@ -270,7 +270,7 @@ bool Entity::IsVisible() const {
void Entity::CalculateNumerical(bool forExport) { void Entity::CalculateNumerical(bool forExport) {
if(IsPoint()) actPoint = PointGetNum(); if(IsPoint()) actPoint = PointGetNum();
if(IsNormal()) actNormal = NormalGetNum(); if(IsNormal()) actNormal = NormalGetNum();
if(type == DISTANCE || type == DISTANCE_N_COPY) { if(type == Type::DISTANCE || type == Type::DISTANCE_N_COPY) {
actDistance = DistanceGetNum(); actDistance = DistanceGetNum();
} }
if(IsFace()) { if(IsFace()) {
@ -435,7 +435,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
int i = sbl->l.n; int i = sbl->l.n;
switch(type) { switch(type) {
case LINE_SEGMENT: { case Type::LINE_SEGMENT: {
Vector a = SK.GetEntity(point[0])->PointGetNum(); Vector a = SK.GetEntity(point[0])->PointGetNum();
Vector b = SK.GetEntity(point[1])->PointGetNum(); Vector b = SK.GetEntity(point[1])->PointGetNum();
sb = SBezier::From(a, b); sb = SBezier::From(a, b);
@ -443,16 +443,16 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
sbl->l.Add(&sb); sbl->l.Add(&sb);
break; break;
} }
case CUBIC: case Type::CUBIC:
ComputeInterpolatingSpline(sbl, false); ComputeInterpolatingSpline(sbl, false);
break; break;
case CUBIC_PERIODIC: case Type::CUBIC_PERIODIC:
ComputeInterpolatingSpline(sbl, true); ComputeInterpolatingSpline(sbl, true);
break; break;
case CIRCLE: case Type::CIRCLE:
case ARC_OF_CIRCLE: { case Type::ARC_OF_CIRCLE: {
Vector center = SK.GetEntity(point[0])->PointGetNum(); Vector center = SK.GetEntity(point[0])->PointGetNum();
Quaternion q = SK.GetEntity(normal)->NormalGetNum(); Quaternion q = SK.GetEntity(normal)->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV(); Vector u = q.RotationU(), v = q.RotationV();
@ -465,7 +465,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
break; break;
} }
if(type == CIRCLE) { if(type == Type::CIRCLE) {
thetaa = 0; thetaa = 0;
thetab = 2*PI; thetab = 2*PI;
dtheta = 2*PI; dtheta = 2*PI;
@ -513,7 +513,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
break; break;
} }
case TTF_TEXT: { case Type::TTF_TEXT: {
Vector topLeft = SK.GetEntity(point[0])->PointGetNum(); Vector topLeft = SK.GetEntity(point[0])->PointGetNum();
Vector botLeft = SK.GetEntity(point[1])->PointGetNum(); Vector botLeft = SK.GetEntity(point[1])->PointGetNum();
Vector n = Normal()->NormalN(); Vector n = Normal()->NormalN();
@ -548,12 +548,12 @@ void Entity::DrawOrGetDistance() {
if(!IsVisible()) return; if(!IsVisible()) return;
switch(type) { switch(type) {
case POINT_N_COPY: case Type::POINT_N_COPY:
case POINT_N_TRANS: case Type::POINT_N_TRANS:
case POINT_N_ROT_TRANS: case Type::POINT_N_ROT_TRANS:
case POINT_N_ROT_AA: case Type::POINT_N_ROT_AA:
case POINT_IN_3D: case Type::POINT_IN_3D:
case POINT_IN_2D: { case Type::POINT_IN_2D: {
Vector v = PointGetNum(); Vector v = PointGetNum();
if(dogd.drawing) { if(dogd.drawing) {
@ -577,11 +577,11 @@ void Entity::DrawOrGetDistance() {
break; break;
} }
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: { case Type::NORMAL_IN_2D: {
int i; int i;
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
if(i == 0 && !SS.GW.showNormals) { if(i == 0 && !SS.GW.showNormals) {
@ -646,12 +646,12 @@ void Entity::DrawOrGetDistance() {
break; break;
} }
case DISTANCE: case Type::DISTANCE:
case DISTANCE_N_COPY: case Type::DISTANCE_N_COPY:
// These are used only as data structures, nothing to display. // These are used only as data structures, nothing to display.
break; break;
case WORKPLANE: { case Type::WORKPLANE: {
Vector p; Vector p;
p = SK.GetEntity(point[0])->PointGetNum(); p = SK.GetEntity(point[0])->PointGetNum();
@ -706,20 +706,20 @@ void Entity::DrawOrGetDistance() {
break; break;
} }
case LINE_SEGMENT: case Type::LINE_SEGMENT:
case CIRCLE: case Type::CIRCLE:
case ARC_OF_CIRCLE: case Type::ARC_OF_CIRCLE:
case CUBIC: case Type::CUBIC:
case CUBIC_PERIODIC: case Type::CUBIC_PERIODIC:
case TTF_TEXT: case Type::TTF_TEXT:
// Nothing but the curve(s). // Nothing but the curve(s).
break; break;
case FACE_NORMAL_PT: case Type::FACE_NORMAL_PT:
case FACE_XPROD: case Type::FACE_XPROD:
case FACE_N_ROT_TRANS: case Type::FACE_N_ROT_TRANS:
case FACE_N_TRANS: case Type::FACE_N_TRANS:
case FACE_N_ROT_AA: case Type::FACE_N_ROT_AA:
// Do nothing; these are drawn with the triangle mesh // Do nothing; these are drawn with the triangle mesh
break; break;

View File

@ -12,12 +12,12 @@ const hEntity EntityBase::NO_ENTITY = { 0 };
bool EntityBase::HasVector() const { bool EntityBase::HasVector() const {
switch(type) { switch(type) {
case LINE_SEGMENT: case Type::LINE_SEGMENT:
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
return true; return true;
default: default:
@ -27,15 +27,15 @@ bool EntityBase::HasVector() const {
ExprVector EntityBase::VectorGetExprs() const { ExprVector EntityBase::VectorGetExprs() const {
switch(type) { switch(type) {
case LINE_SEGMENT: case Type::LINE_SEGMENT:
return (SK.GetEntity(point[0])->PointGetExprs()).Minus( return (SK.GetEntity(point[0])->PointGetExprs()).Minus(
SK.GetEntity(point[1])->PointGetExprs()); SK.GetEntity(point[1])->PointGetExprs());
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
return NormalExprsN(); return NormalExprsN();
default: ssassert(false, "Unexpected entity type"); default: ssassert(false, "Unexpected entity type");
@ -44,15 +44,15 @@ ExprVector EntityBase::VectorGetExprs() const {
Vector EntityBase::VectorGetNum() const { Vector EntityBase::VectorGetNum() const {
switch(type) { switch(type) {
case LINE_SEGMENT: case Type::LINE_SEGMENT:
return (SK.GetEntity(point[0])->PointGetNum()).Minus( return (SK.GetEntity(point[0])->PointGetNum()).Minus(
SK.GetEntity(point[1])->PointGetNum()); SK.GetEntity(point[1])->PointGetNum());
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
return NormalN(); return NormalN();
default: ssassert(false, "Unexpected entity type"); default: ssassert(false, "Unexpected entity type");
@ -61,15 +61,15 @@ Vector EntityBase::VectorGetNum() const {
Vector EntityBase::VectorGetRefPoint() const { Vector EntityBase::VectorGetRefPoint() const {
switch(type) { switch(type) {
case LINE_SEGMENT: case Type::LINE_SEGMENT:
return ((SK.GetEntity(point[0])->PointGetNum()).Plus( return ((SK.GetEntity(point[0])->PointGetNum()).Plus(
SK.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5); SK.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5);
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
return SK.GetEntity(point[0])->PointGetNum(); return SK.GetEntity(point[0])->PointGetNum();
default: ssassert(false, "Unexpected entity type"); default: ssassert(false, "Unexpected entity type");
@ -78,14 +78,14 @@ Vector EntityBase::VectorGetRefPoint() const {
Vector EntityBase::VectorGetStartPoint() const { Vector EntityBase::VectorGetStartPoint() const {
switch(type) { switch(type) {
case LINE_SEGMENT: case Type::LINE_SEGMENT:
return SK.GetEntity(point[1])->PointGetNum(); return SK.GetEntity(point[1])->PointGetNum();
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
return SK.GetEntity(point[0])->PointGetNum(); return SK.GetEntity(point[0])->PointGetNum();
default: ssassert(false, "Unexpected entity type"); default: ssassert(false, "Unexpected entity type");
@ -93,21 +93,21 @@ Vector EntityBase::VectorGetStartPoint() const {
} }
bool EntityBase::IsCircle() const { bool EntityBase::IsCircle() const {
return (type == CIRCLE) || (type == ARC_OF_CIRCLE); return (type == Type::CIRCLE) || (type == Type::ARC_OF_CIRCLE);
} }
Expr *EntityBase::CircleGetRadiusExpr() const { Expr *EntityBase::CircleGetRadiusExpr() const {
if(type == CIRCLE) { if(type == Type::CIRCLE) {
return SK.GetEntity(distance)->DistanceGetExpr(); return SK.GetEntity(distance)->DistanceGetExpr();
} else if(type == ARC_OF_CIRCLE) { } else if(type == Type::ARC_OF_CIRCLE) {
return Constraint::Distance(workplane, point[0], point[1]); return Constraint::Distance(workplane, point[0], point[1]);
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
} }
double EntityBase::CircleGetRadiusNum() const { double EntityBase::CircleGetRadiusNum() const {
if(type == CIRCLE) { if(type == Type::CIRCLE) {
return SK.GetEntity(distance)->DistanceGetNum(); return SK.GetEntity(distance)->DistanceGetNum();
} else if(type == ARC_OF_CIRCLE) { } else if(type == Type::ARC_OF_CIRCLE) {
Vector c = SK.GetEntity(point[0])->PointGetNum(); Vector c = SK.GetEntity(point[0])->PointGetNum();
Vector pa = SK.GetEntity(point[1])->PointGetNum(); Vector pa = SK.GetEntity(point[1])->PointGetNum();
return (pa.Minus(c)).Magnitude(); return (pa.Minus(c)).Magnitude();
@ -115,7 +115,7 @@ double EntityBase::CircleGetRadiusNum() const {
} }
void EntityBase::ArcGetAngles(double *thetaa, double *thetab, double *dtheta) const { void EntityBase::ArcGetAngles(double *thetaa, double *thetab, double *dtheta) const {
ssassert(type == ARC_OF_CIRCLE, "Unexpected entity type"); ssassert(type == Type::ARC_OF_CIRCLE, "Unexpected entity type");
Quaternion q = Normal()->NormalGetNum(); Quaternion q = Normal()->NormalGetNum();
Vector u = q.RotationU(), v = q.RotationV(); Vector u = q.RotationU(), v = q.RotationV();
@ -165,7 +165,7 @@ Vector EntityBase::CubicGetFinishTangentNum() const {
} }
bool EntityBase::IsWorkplane() const { bool EntityBase::IsWorkplane() const {
return (type == WORKPLANE); return (type == Type::WORKPLANE);
} }
ExprVector EntityBase::WorkplaneGetOffsetExprs() const { ExprVector EntityBase::WorkplaneGetOffsetExprs() const {
@ -177,7 +177,7 @@ Vector EntityBase::WorkplaneGetOffset() const {
} }
void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) const { void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) const {
if(type == WORKPLANE) { if(type == Type::WORKPLANE) {
*n = Normal()->NormalExprsN(); *n = Normal()->NormalExprsN();
ExprVector p0 = SK.GetEntity(point[0])->PointGetExprs(); ExprVector p0 = SK.GetEntity(point[0])->PointGetExprs();
@ -189,27 +189,27 @@ void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) const {
} }
bool EntityBase::IsDistance() const { bool EntityBase::IsDistance() const {
return (type == DISTANCE) || return (type == Type::DISTANCE) ||
(type == DISTANCE_N_COPY); (type == Type::DISTANCE_N_COPY);
} }
double EntityBase::DistanceGetNum() const { double EntityBase::DistanceGetNum() const {
if(type == DISTANCE) { if(type == Type::DISTANCE) {
return SK.GetParam(param[0])->val; return SK.GetParam(param[0])->val;
} else if(type == DISTANCE_N_COPY) { } else if(type == Type::DISTANCE_N_COPY) {
return numDistance; return numDistance;
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
} }
Expr *EntityBase::DistanceGetExpr() const { Expr *EntityBase::DistanceGetExpr() const {
if(type == DISTANCE) { if(type == Type::DISTANCE) {
return Expr::From(param[0]); return Expr::From(param[0]);
} else if(type == DISTANCE_N_COPY) { } else if(type == Type::DISTANCE_N_COPY) {
return Expr::From(numDistance); return Expr::From(numDistance);
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
} }
void EntityBase::DistanceForceTo(double v) { void EntityBase::DistanceForceTo(double v) {
if(type == DISTANCE) { if(type == Type::DISTANCE) {
(SK.GetParam(param[0]))->val = v; (SK.GetParam(param[0]))->val = v;
} else if(type == DISTANCE_N_COPY) { } else if(type == Type::DISTANCE_N_COPY) {
// do nothing, it's locked // do nothing, it's locked
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
} }
@ -220,12 +220,12 @@ EntityBase *EntityBase::Normal() const {
bool EntityBase::IsPoint() const { bool EntityBase::IsPoint() const {
switch(type) { switch(type) {
case POINT_IN_3D: case Type::POINT_IN_3D:
case POINT_IN_2D: case Type::POINT_IN_2D:
case POINT_N_COPY: case Type::POINT_N_COPY:
case POINT_N_TRANS: case Type::POINT_N_TRANS:
case POINT_N_ROT_TRANS: case Type::POINT_N_ROT_TRANS:
case POINT_N_ROT_AA: case Type::POINT_N_ROT_AA:
return true; return true;
default: default:
@ -235,11 +235,11 @@ bool EntityBase::IsPoint() const {
bool EntityBase::IsNormal() const { bool EntityBase::IsNormal() const {
switch(type) { switch(type) {
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
return true; return true;
default: return false; default: return false;
@ -249,26 +249,26 @@ bool EntityBase::IsNormal() const {
Quaternion EntityBase::NormalGetNum() const { Quaternion EntityBase::NormalGetNum() const {
Quaternion q; Quaternion q;
switch(type) { switch(type) {
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
q = Quaternion::From(param[0], param[1], param[2], param[3]); q = Quaternion::From(param[0], param[1], param[2], param[3]);
break; break;
case NORMAL_IN_2D: { case Type::NORMAL_IN_2D: {
EntityBase *wrkpl = SK.GetEntity(workplane); EntityBase *wrkpl = SK.GetEntity(workplane);
EntityBase *norm = SK.GetEntity(wrkpl->normal); EntityBase *norm = SK.GetEntity(wrkpl->normal);
q = norm->NormalGetNum(); q = norm->NormalGetNum();
break; break;
} }
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
q = numNormal; q = numNormal;
break; break;
case NORMAL_N_ROT: case Type::NORMAL_N_ROT:
q = Quaternion::From(param[0], param[1], param[2], param[3]); q = Quaternion::From(param[0], param[1], param[2], param[3]);
q = q.Times(numNormal); q = q.Times(numNormal);
break; break;
case NORMAL_N_ROT_AA: { case Type::NORMAL_N_ROT_AA: {
q = GetAxisAngleQuaternion(0); q = GetAxisAngleQuaternion(0);
q = q.Times(numNormal); q = q.Times(numNormal);
break; break;
@ -281,18 +281,18 @@ Quaternion EntityBase::NormalGetNum() const {
void EntityBase::NormalForceTo(Quaternion q) { void EntityBase::NormalForceTo(Quaternion q) {
switch(type) { switch(type) {
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
SK.GetParam(param[0])->val = q.w; SK.GetParam(param[0])->val = q.w;
SK.GetParam(param[1])->val = q.vx; SK.GetParam(param[1])->val = q.vx;
SK.GetParam(param[2])->val = q.vy; SK.GetParam(param[2])->val = q.vy;
SK.GetParam(param[3])->val = q.vz; SK.GetParam(param[3])->val = q.vz;
break; break;
case NORMAL_IN_2D: case Type::NORMAL_IN_2D:
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
// There's absolutely nothing to do; these are locked. // There's absolutely nothing to do; these are locked.
break; break;
case NORMAL_N_ROT: { case Type::NORMAL_N_ROT: {
Quaternion qp = q.Times(numNormal.Inverse()); Quaternion qp = q.Times(numNormal.Inverse());
SK.GetParam(param[0])->val = qp.w; SK.GetParam(param[0])->val = qp.w;
@ -302,7 +302,7 @@ void EntityBase::NormalForceTo(Quaternion q) {
break; break;
} }
case NORMAL_N_ROT_AA: case Type::NORMAL_N_ROT_AA:
// Not sure if I'll bother implementing this one // Not sure if I'll bother implementing this one
break; break;
@ -333,21 +333,21 @@ ExprVector EntityBase::NormalExprsN() const {
ExprQuaternion EntityBase::NormalGetExprs() const { ExprQuaternion EntityBase::NormalGetExprs() const {
ExprQuaternion q; ExprQuaternion q;
switch(type) { switch(type) {
case NORMAL_IN_3D: case Type::NORMAL_IN_3D:
q = ExprQuaternion::From(param[0], param[1], param[2], param[3]); q = ExprQuaternion::From(param[0], param[1], param[2], param[3]);
break; break;
case NORMAL_IN_2D: { case Type::NORMAL_IN_2D: {
EntityBase *wrkpl = SK.GetEntity(workplane); EntityBase *wrkpl = SK.GetEntity(workplane);
EntityBase *norm = SK.GetEntity(wrkpl->normal); EntityBase *norm = SK.GetEntity(wrkpl->normal);
q = norm->NormalGetExprs(); q = norm->NormalGetExprs();
break; break;
} }
case NORMAL_N_COPY: case Type::NORMAL_N_COPY:
q = ExprQuaternion::From(numNormal); q = ExprQuaternion::From(numNormal);
break; break;
case NORMAL_N_ROT: { case Type::NORMAL_N_ROT: {
ExprQuaternion orig = ExprQuaternion::From(numNormal); ExprQuaternion orig = ExprQuaternion::From(numNormal);
q = ExprQuaternion::From(param[0], param[1], param[2], param[3]); q = ExprQuaternion::From(param[0], param[1], param[2], param[3]);
@ -355,7 +355,7 @@ ExprQuaternion EntityBase::NormalGetExprs() const {
break; break;
} }
case NORMAL_N_ROT_AA: { case Type::NORMAL_N_ROT_AA: {
ExprQuaternion orig = ExprQuaternion::From(numNormal); ExprQuaternion orig = ExprQuaternion::From(numNormal);
q = GetAxisAngleQuaternionExprs(0); q = GetAxisAngleQuaternionExprs(0);
q = q.Times(orig); q = q.Times(orig);
@ -369,13 +369,13 @@ ExprQuaternion EntityBase::NormalGetExprs() const {
void EntityBase::PointForceTo(Vector p) { void EntityBase::PointForceTo(Vector p) {
switch(type) { switch(type) {
case POINT_IN_3D: case Type::POINT_IN_3D:
SK.GetParam(param[0])->val = p.x; SK.GetParam(param[0])->val = p.x;
SK.GetParam(param[1])->val = p.y; SK.GetParam(param[1])->val = p.y;
SK.GetParam(param[2])->val = p.z; SK.GetParam(param[2])->val = p.z;
break; break;
case POINT_IN_2D: { case Type::POINT_IN_2D: {
EntityBase *c = SK.GetEntity(workplane); EntityBase *c = SK.GetEntity(workplane);
p = p.Minus(c->WorkplaneGetOffset()); p = p.Minus(c->WorkplaneGetOffset());
SK.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU()); SK.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU());
@ -383,7 +383,7 @@ void EntityBase::PointForceTo(Vector p) {
break; break;
} }
case POINT_N_TRANS: { case Type::POINT_N_TRANS: {
if(timesApplied == 0) break; if(timesApplied == 0) break;
Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied); Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied);
SK.GetParam(param[0])->val = trans.x; SK.GetParam(param[0])->val = trans.x;
@ -392,7 +392,7 @@ void EntityBase::PointForceTo(Vector p) {
break; break;
} }
case POINT_N_ROT_TRANS: { case Type::POINT_N_ROT_TRANS: {
// Force only the translation; leave the rotation unchanged. But // Force only the translation; leave the rotation unchanged. But
// remember that we're working with respect to the rotated // remember that we're working with respect to the rotated
// point. // point.
@ -403,7 +403,7 @@ void EntityBase::PointForceTo(Vector p) {
break; break;
} }
case POINT_N_ROT_AA: { case Type::POINT_N_ROT_AA: {
// Force only the angle; the axis and center of rotation stay // Force only the angle; the axis and center of rotation stay
Vector offset = Vector::From(param[0], param[1], param[2]); Vector offset = Vector::From(param[0], param[1], param[2]);
Vector normal = Vector::From(param[4], param[5], param[6]); Vector normal = Vector::From(param[4], param[5], param[6]);
@ -422,7 +422,7 @@ void EntityBase::PointForceTo(Vector p) {
break; break;
} }
case POINT_N_COPY: case Type::POINT_N_COPY:
// Nothing to do; it's a static copy // Nothing to do; it's a static copy
break; break;
@ -433,11 +433,11 @@ void EntityBase::PointForceTo(Vector p) {
Vector EntityBase::PointGetNum() const { Vector EntityBase::PointGetNum() const {
Vector p; Vector p;
switch(type) { switch(type) {
case POINT_IN_3D: case Type::POINT_IN_3D:
p = Vector::From(param[0], param[1], param[2]); p = Vector::From(param[0], param[1], param[2]);
break; break;
case POINT_IN_2D: { case Type::POINT_IN_2D: {
EntityBase *c = SK.GetEntity(workplane); EntityBase *c = SK.GetEntity(workplane);
Vector u = c->Normal()->NormalU(); Vector u = c->Normal()->NormalU();
Vector v = c->Normal()->NormalV(); Vector v = c->Normal()->NormalV();
@ -447,13 +447,13 @@ Vector EntityBase::PointGetNum() const {
break; break;
} }
case POINT_N_TRANS: { case Type::POINT_N_TRANS: {
Vector trans = Vector::From(param[0], param[1], param[2]); Vector trans = Vector::From(param[0], param[1], param[2]);
p = numPoint.Plus(trans.ScaledBy(timesApplied)); p = numPoint.Plus(trans.ScaledBy(timesApplied));
break; break;
} }
case POINT_N_ROT_TRANS: { case Type::POINT_N_ROT_TRANS: {
Vector offset = Vector::From(param[0], param[1], param[2]); Vector offset = Vector::From(param[0], param[1], param[2]);
Quaternion q = PointGetQuaternion(); Quaternion q = PointGetQuaternion();
p = q.Rotate(numPoint); p = q.Rotate(numPoint);
@ -461,7 +461,7 @@ Vector EntityBase::PointGetNum() const {
break; break;
} }
case POINT_N_ROT_AA: { case Type::POINT_N_ROT_AA: {
Vector offset = Vector::From(param[0], param[1], param[2]); Vector offset = Vector::From(param[0], param[1], param[2]);
Quaternion q = PointGetQuaternion(); Quaternion q = PointGetQuaternion();
p = numPoint.Minus(offset); p = numPoint.Minus(offset);
@ -470,7 +470,7 @@ Vector EntityBase::PointGetNum() const {
break; break;
} }
case POINT_N_COPY: case Type::POINT_N_COPY:
p = numPoint; p = numPoint;
break; break;
@ -482,11 +482,11 @@ Vector EntityBase::PointGetNum() const {
ExprVector EntityBase::PointGetExprs() const { ExprVector EntityBase::PointGetExprs() const {
ExprVector r; ExprVector r;
switch(type) { switch(type) {
case POINT_IN_3D: case Type::POINT_IN_3D:
r = ExprVector::From(param[0], param[1], param[2]); r = ExprVector::From(param[0], param[1], param[2]);
break; break;
case POINT_IN_2D: { case Type::POINT_IN_2D: {
EntityBase *c = SK.GetEntity(workplane); EntityBase *c = SK.GetEntity(workplane);
ExprVector u = c->Normal()->NormalExprsU(); ExprVector u = c->Normal()->NormalExprsU();
ExprVector v = c->Normal()->NormalExprsV(); ExprVector v = c->Normal()->NormalExprsV();
@ -495,13 +495,13 @@ ExprVector EntityBase::PointGetExprs() const {
r = r.Plus(v.ScaledBy(Expr::From(param[1]))); r = r.Plus(v.ScaledBy(Expr::From(param[1])));
break; break;
} }
case POINT_N_TRANS: { case Type::POINT_N_TRANS: {
ExprVector orig = ExprVector::From(numPoint); ExprVector orig = ExprVector::From(numPoint);
ExprVector trans = ExprVector::From(param[0], param[1], param[2]); ExprVector trans = ExprVector::From(param[0], param[1], param[2]);
r = orig.Plus(trans.ScaledBy(Expr::From(timesApplied))); r = orig.Plus(trans.ScaledBy(Expr::From(timesApplied)));
break; break;
} }
case POINT_N_ROT_TRANS: { case Type::POINT_N_ROT_TRANS: {
ExprVector orig = ExprVector::From(numPoint); ExprVector orig = ExprVector::From(numPoint);
ExprVector trans = ExprVector::From(param[0], param[1], param[2]); ExprVector trans = ExprVector::From(param[0], param[1], param[2]);
ExprQuaternion q = ExprQuaternion q =
@ -510,7 +510,7 @@ ExprVector EntityBase::PointGetExprs() const {
r = orig.Plus(trans); r = orig.Plus(trans);
break; break;
} }
case POINT_N_ROT_AA: { case Type::POINT_N_ROT_AA: {
ExprVector orig = ExprVector::From(numPoint); ExprVector orig = ExprVector::From(numPoint);
ExprVector trans = ExprVector::From(param[0], param[1], param[2]); ExprVector trans = ExprVector::From(param[0], param[1], param[2]);
ExprQuaternion q = GetAxisAngleQuaternionExprs(3); ExprQuaternion q = GetAxisAngleQuaternionExprs(3);
@ -519,7 +519,7 @@ ExprVector EntityBase::PointGetExprs() const {
r = orig.Plus(trans); r = orig.Plus(trans);
break; break;
} }
case POINT_N_COPY: case Type::POINT_N_COPY:
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
break; break;
@ -529,7 +529,7 @@ ExprVector EntityBase::PointGetExprs() const {
} }
void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) const { void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) const {
if(type == POINT_IN_2D && workplane.v == wrkpl.v) { if(type == Type::POINT_IN_2D && workplane.v == wrkpl.v) {
// They want our coordinates in the form that we've written them, // They want our coordinates in the form that we've written them,
// very nice. // very nice.
*u = Expr::From(param[0]); *u = Expr::From(param[0]);
@ -551,7 +551,7 @@ void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) con
} }
void EntityBase::PointForceQuaternionTo(Quaternion q) { void EntityBase::PointForceQuaternionTo(Quaternion q) {
ssassert(type == POINT_N_ROT_TRANS, "Unexpected entity type"); ssassert(type == Type::POINT_N_ROT_TRANS, "Unexpected entity type");
SK.GetParam(param[3])->val = q.w; SK.GetParam(param[3])->val = q.w;
SK.GetParam(param[4])->val = q.vx; SK.GetParam(param[4])->val = q.vx;
@ -586,9 +586,9 @@ ExprQuaternion EntityBase::GetAxisAngleQuaternionExprs(int param0) const {
Quaternion EntityBase::PointGetQuaternion() const { Quaternion EntityBase::PointGetQuaternion() const {
Quaternion q; Quaternion q;
if(type == POINT_N_ROT_AA) { if(type == Type::POINT_N_ROT_AA) {
q = GetAxisAngleQuaternion(3); q = GetAxisAngleQuaternion(3);
} else if(type == POINT_N_ROT_TRANS) { } else if(type == Type::POINT_N_ROT_TRANS) {
q = Quaternion::From(param[3], param[4], param[5], param[6]); q = Quaternion::From(param[3], param[4], param[5], param[6]);
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
@ -597,11 +597,11 @@ Quaternion EntityBase::PointGetQuaternion() const {
bool EntityBase::IsFace() const { bool EntityBase::IsFace() const {
switch(type) { switch(type) {
case FACE_NORMAL_PT: case Type::FACE_NORMAL_PT:
case FACE_XPROD: case Type::FACE_XPROD:
case FACE_N_ROT_TRANS: case Type::FACE_N_ROT_TRANS:
case FACE_N_TRANS: case Type::FACE_N_TRANS:
case FACE_N_ROT_AA: case Type::FACE_N_ROT_AA:
return true; return true;
default: default:
return false; return false;
@ -610,16 +610,16 @@ bool EntityBase::IsFace() const {
ExprVector EntityBase::FaceGetNormalExprs() const { ExprVector EntityBase::FaceGetNormalExprs() const {
ExprVector r; ExprVector r;
if(type == FACE_NORMAL_PT) { if(type == Type::FACE_NORMAL_PT) {
Vector v = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); Vector v = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
r = ExprVector::From(v.WithMagnitude(1)); r = ExprVector::From(v.WithMagnitude(1));
} else if(type == FACE_XPROD) { } else if(type == Type::FACE_XPROD) {
ExprVector vc = ExprVector::From(param[0], param[1], param[2]); ExprVector vc = ExprVector::From(param[0], param[1], param[2]);
ExprVector vn = ExprVector vn =
ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
r = vc.Cross(vn); r = vc.Cross(vn);
r = r.WithMagnitude(Expr::From(1.0)); r = r.WithMagnitude(Expr::From(1.0));
} else if(type == FACE_N_ROT_TRANS) { } else if(type == Type::FACE_N_ROT_TRANS) {
// The numerical normal vector gets the rotation; the numerical // The numerical normal vector gets the rotation; the numerical
// normal has magnitude one, and the rotation doesn't change that, // normal has magnitude one, and the rotation doesn't change that,
// so there's no need to fix it up. // so there's no need to fix it up.
@ -627,9 +627,9 @@ ExprVector EntityBase::FaceGetNormalExprs() const {
ExprQuaternion q = ExprQuaternion q =
ExprQuaternion::From(param[3], param[4], param[5], param[6]); ExprQuaternion::From(param[3], param[4], param[5], param[6]);
r = q.Rotate(r); r = q.Rotate(r);
} else if(type == FACE_N_TRANS) { } else if(type == Type::FACE_N_TRANS) {
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
} else if(type == FACE_N_ROT_AA) { } else if(type == Type::FACE_N_ROT_AA) {
r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz);
ExprQuaternion q = GetAxisAngleQuaternionExprs(3); ExprQuaternion q = GetAxisAngleQuaternionExprs(3);
r = q.Rotate(r); r = q.Rotate(r);
@ -639,20 +639,20 @@ ExprVector EntityBase::FaceGetNormalExprs() const {
Vector EntityBase::FaceGetNormalNum() const { Vector EntityBase::FaceGetNormalNum() const {
Vector r; Vector r;
if(type == FACE_NORMAL_PT) { if(type == Type::FACE_NORMAL_PT) {
r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
} else if(type == FACE_XPROD) { } else if(type == Type::FACE_XPROD) {
Vector vc = Vector::From(param[0], param[1], param[2]); Vector vc = Vector::From(param[0], param[1], param[2]);
Vector vn = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); Vector vn = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
r = vc.Cross(vn); r = vc.Cross(vn);
} else if(type == FACE_N_ROT_TRANS) { } else if(type == Type::FACE_N_ROT_TRANS) {
// The numerical normal vector gets the rotation // The numerical normal vector gets the rotation
r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]); Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]);
r = q.Rotate(r); r = q.Rotate(r);
} else if(type == FACE_N_TRANS) { } else if(type == Type::FACE_N_TRANS) {
r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
} else if(type == FACE_N_ROT_AA) { } else if(type == Type::FACE_N_ROT_AA) {
r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz);
Quaternion q = GetAxisAngleQuaternion(3); Quaternion q = GetAxisAngleQuaternion(3);
r = q.Rotate(r); r = q.Rotate(r);
@ -662,11 +662,11 @@ Vector EntityBase::FaceGetNormalNum() const {
ExprVector EntityBase::FaceGetPointExprs() const { ExprVector EntityBase::FaceGetPointExprs() const {
ExprVector r; ExprVector r;
if(type == FACE_NORMAL_PT) { if(type == Type::FACE_NORMAL_PT) {
r = SK.GetEntity(point[0])->PointGetExprs(); r = SK.GetEntity(point[0])->PointGetExprs();
} else if(type == FACE_XPROD) { } else if(type == Type::FACE_XPROD) {
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
} else if(type == FACE_N_ROT_TRANS) { } else if(type == Type::FACE_N_ROT_TRANS) {
// The numerical point gets the rotation and translation. // The numerical point gets the rotation and translation.
ExprVector trans = ExprVector::From(param[0], param[1], param[2]); ExprVector trans = ExprVector::From(param[0], param[1], param[2]);
ExprQuaternion q = ExprQuaternion q =
@ -674,11 +674,11 @@ ExprVector EntityBase::FaceGetPointExprs() const {
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
r = q.Rotate(r); r = q.Rotate(r);
r = r.Plus(trans); r = r.Plus(trans);
} else if(type == FACE_N_TRANS) { } else if(type == Type::FACE_N_TRANS) {
ExprVector trans = ExprVector::From(param[0], param[1], param[2]); ExprVector trans = ExprVector::From(param[0], param[1], param[2]);
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
r = r.Plus(trans.ScaledBy(Expr::From(timesApplied))); r = r.Plus(trans.ScaledBy(Expr::From(timesApplied)));
} else if(type == FACE_N_ROT_AA) { } else if(type == Type::FACE_N_ROT_AA) {
ExprVector trans = ExprVector::From(param[0], param[1], param[2]); ExprVector trans = ExprVector::From(param[0], param[1], param[2]);
ExprQuaternion q = GetAxisAngleQuaternionExprs(3); ExprQuaternion q = GetAxisAngleQuaternionExprs(3);
r = ExprVector::From(numPoint); r = ExprVector::From(numPoint);
@ -691,20 +691,20 @@ ExprVector EntityBase::FaceGetPointExprs() const {
Vector EntityBase::FaceGetPointNum() const { Vector EntityBase::FaceGetPointNum() const {
Vector r; Vector r;
if(type == FACE_NORMAL_PT) { if(type == Type::FACE_NORMAL_PT) {
r = SK.GetEntity(point[0])->PointGetNum(); r = SK.GetEntity(point[0])->PointGetNum();
} else if(type == FACE_XPROD) { } else if(type == Type::FACE_XPROD) {
r = numPoint; r = numPoint;
} else if(type == FACE_N_ROT_TRANS) { } else if(type == Type::FACE_N_ROT_TRANS) {
// The numerical point gets the rotation and translation. // The numerical point gets the rotation and translation.
Vector trans = Vector::From(param[0], param[1], param[2]); Vector trans = Vector::From(param[0], param[1], param[2]);
Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]); Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]);
r = q.Rotate(numPoint); r = q.Rotate(numPoint);
r = r.Plus(trans); r = r.Plus(trans);
} else if(type == FACE_N_TRANS) { } else if(type == Type::FACE_N_TRANS) {
Vector trans = Vector::From(param[0], param[1], param[2]); Vector trans = Vector::From(param[0], param[1], param[2]);
r = numPoint.Plus(trans.ScaledBy(timesApplied)); r = numPoint.Plus(trans.ScaledBy(timesApplied));
} else if(type == FACE_N_ROT_AA) { } else if(type == Type::FACE_N_ROT_AA) {
Vector trans = Vector::From(param[0], param[1], param[2]); Vector trans = Vector::From(param[0], param[1], param[2]);
Quaternion q = GetAxisAngleQuaternion(3); Quaternion q = GetAxisAngleQuaternion(3);
r = numPoint.Minus(trans); r = numPoint.Minus(trans);
@ -715,25 +715,25 @@ Vector EntityBase::FaceGetPointNum() const {
} }
bool EntityBase::HasEndpoints() const { bool EntityBase::HasEndpoints() const {
return (type == LINE_SEGMENT) || return (type == Type::LINE_SEGMENT) ||
(type == CUBIC) || (type == Type::CUBIC) ||
(type == ARC_OF_CIRCLE); (type == Type::ARC_OF_CIRCLE);
} }
Vector EntityBase::EndpointStart() const { Vector EntityBase::EndpointStart() const {
if(type == LINE_SEGMENT) { if(type == Type::LINE_SEGMENT) {
return SK.GetEntity(point[0])->PointGetNum(); return SK.GetEntity(point[0])->PointGetNum();
} else if(type == CUBIC) { } else if(type == Type::CUBIC) {
return CubicGetStartNum(); return CubicGetStartNum();
} else if(type == ARC_OF_CIRCLE) { } else if(type == Type::ARC_OF_CIRCLE) {
return SK.GetEntity(point[1])->PointGetNum(); return SK.GetEntity(point[1])->PointGetNum();
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
} }
Vector EntityBase::EndpointFinish() const { Vector EntityBase::EndpointFinish() const {
if(type == LINE_SEGMENT) { if(type == Type::LINE_SEGMENT) {
return SK.GetEntity(point[1])->PointGetNum(); return SK.GetEntity(point[1])->PointGetNum();
} else if(type == CUBIC) { } else if(type == Type::CUBIC) {
return CubicGetFinishNum(); return CubicGetFinishNum();
} else if(type == ARC_OF_CIRCLE) { } else if(type == Type::ARC_OF_CIRCLE) {
return SK.GetEntity(point[2])->PointGetNum(); return SK.GetEntity(point[2])->PointGetNum();
} else ssassert(false, "Unexpected entity type"); } else ssassert(false, "Unexpected entity type");
} }
@ -747,16 +747,16 @@ void EntityBase::AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) con
void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const { void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const {
switch(type) { switch(type) {
case NORMAL_IN_3D: { case Type::NORMAL_IN_3D: {
ExprQuaternion q = NormalGetExprs(); ExprQuaternion q = NormalGetExprs();
AddEq(l, (q.Magnitude())->Minus(Expr::From(1)), 0); AddEq(l, (q.Magnitude())->Minus(Expr::From(1)), 0);
break; break;
} }
case ARC_OF_CIRCLE: { case Type::ARC_OF_CIRCLE: {
// If this is a copied entity, with its point already fixed // If this is a copied entity, with its point already fixed
// with respect to each other, then we don't want to generate // with respect to each other, then we don't want to generate
// the distance constraint! // the distance constraint!
if(SK.GetEntity(point[0])->type != POINT_IN_2D) break; if(SK.GetEntity(point[0])->type != Type::POINT_IN_2D) break;
// If the two endpoints of the arc are constrained coincident // If the two endpoints of the arc are constrained coincident
// (to make a complete circle), then our distance constraint // (to make a complete circle), then our distance constraint
@ -765,7 +765,7 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const {
for(i = 0; i < SK.constraint.n; i++) { for(i = 0; i < SK.constraint.n; i++) {
ConstraintBase *c = &(SK.constraint.elem[i]); ConstraintBase *c = &(SK.constraint.elem[i]);
if(c->group.v != group.v) continue; if(c->group.v != group.v) continue;
if(c->type != Constraint::POINTS_COINCIDENT) continue; if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
if((c->ptA.v == point[1].v && c->ptB.v == point[2].v) || if((c->ptA.v == point[1].v && c->ptB.v == point[2].v) ||
(c->ptA.v == point[2].v && c->ptB.v == point[1].v)) (c->ptA.v == point[2].v && c->ptB.v == point[1].v))
@ -784,4 +784,3 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const {
// Most entities do not generate equations. // Most entities do not generate equations.
} }
} }

View File

@ -119,7 +119,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool wir
if(!out) return; if(!out) return;
SS.exportMode = true; SS.exportMode = true;
GenerateAll(GENERATE_ALL); GenerateAll(Generate::ALL);
SMesh *sm = NULL; SMesh *sm = NULL;
if(SS.GW.showShaded || SS.GW.showHdnLines) { if(SS.GW.showShaded || SS.GW.showHdnLines) {
@ -332,7 +332,7 @@ void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *s
// Generate the edges where a curved surface turns from front-facing // Generate the edges where a curved surface turns from front-facing
// to back-facing. // to back-facing.
if(SS.GW.showEdges) { if(SS.GW.showEdges) {
root->MakeCertainEdgesInto(sel, SKdNode::TURNING_EDGES, root->MakeCertainEdgesInto(sel, EdgeKind::TURNING,
/*coplanarIsInter=*/false, NULL, NULL, /*coplanarIsInter=*/false, NULL, NULL,
GW.showOutlines ? Style::OUTLINE : Style::SOLID_EDGE); GW.showOutlines ? Style::OUTLINE : Style::SOLID_EDGE);
} }
@ -727,7 +727,7 @@ void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SolveSpaceUI::ExportMeshTo(const std::string &filename) { void SolveSpaceUI::ExportMeshTo(const std::string &filename) {
SS.exportMode = true; SS.exportMode = true;
GenerateAll(GENERATE_ALL); GenerateAll(Generate::ALL);
Group *g = SK.GetGroup(SS.GW.activeGroup); Group *g = SK.GetGroup(SS.GW.activeGroup);
g->GenerateDisplayItems(); g->GenerateDisplayItems();

View File

@ -189,39 +189,40 @@ public:
} }
void writeLTypes() override { void writeLTypes() override {
for(int i = 0; i <= Style::LAST_STIPPLE; i++) { for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) {
StipplePattern st = (StipplePattern)i;
DRW_LType type; DRW_LType type;
// LibreCAD requires the line type to have one of these exact names, // LibreCAD requires the line type to have one of these exact names,
// or otherwise it overwrites it with its own (continuous) style. // or otherwise it overwrites it with its own (continuous) style.
type.name = DxfFileWriter::lineTypeName(i); type.name = DxfFileWriter::lineTypeName(st);
double sw = 1.0; double sw = 1.0;
switch(i) { switch(st) {
case Style::STIPPLE_CONTINUOUS: case StipplePattern::CONTINUOUS:
break; break;
case Style::STIPPLE_DASH: case StipplePattern::DASH:
type.path.push_back(sw); type.path.push_back(sw);
type.path.push_back(-sw); type.path.push_back(-sw);
break; break;
case Style::STIPPLE_LONG_DASH: case StipplePattern::LONG_DASH:
type.path.push_back(sw * 2.0); type.path.push_back(sw * 2.0);
type.path.push_back(-sw); type.path.push_back(-sw);
break; break;
case Style::STIPPLE_DASH_DOT: case StipplePattern::DASH_DOT:
type.path.push_back(sw); type.path.push_back(sw);
type.path.push_back(-sw); type.path.push_back(-sw);
type.path.push_back(0.0); type.path.push_back(0.0);
type.path.push_back(-sw); type.path.push_back(-sw);
break; break;
case Style::STIPPLE_DOT: case StipplePattern::DOT:
type.path.push_back(sw); type.path.push_back(sw);
type.path.push_back(0.0); type.path.push_back(0.0);
break; break;
case Style::STIPPLE_DASH_DOT_DOT: case StipplePattern::DASH_DOT_DOT:
type.path.push_back(sw); type.path.push_back(sw);
type.path.push_back(-sw); type.path.push_back(-sw);
type.path.push_back(0.0); type.path.push_back(0.0);
@ -294,7 +295,7 @@ public:
for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) { for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) {
if(!writer->NeedToOutput(c)) continue; if(!writer->NeedToOutput(c)) continue;
switch(c->type) { switch(c->type) {
case Constraint::PT_PT_DISTANCE: { case Constraint::Type::PT_PT_DISTANCE: {
Vector ap = SK.GetEntity(c->ptA)->PointGetNum(); Vector ap = SK.GetEntity(c->ptA)->PointGetNum();
Vector bp = SK.GetEntity(c->ptB)->PointGetNum(); Vector bp = SK.GetEntity(c->ptB)->PointGetNum();
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset); Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset);
@ -303,7 +304,7 @@ public:
break; break;
} }
case Constraint::PT_LINE_DISTANCE: { case Constraint::Type::PT_LINE_DISTANCE: {
Vector pt = SK.GetEntity(c->ptA)->PointGetNum(); Vector pt = SK.GetEntity(c->ptA)->PointGetNum();
Entity *line = SK.GetEntity(c->entityA); Entity *line = SK.GetEntity(c->entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum(); Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
@ -335,7 +336,7 @@ public:
break; break;
} }
case Constraint::DIAMETER: { case Constraint::Type::DIAMETER: {
Entity *circle = SK.GetEntity(c->entityA); Entity *circle = SK.GetEntity(c->entityA);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum(); Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
@ -359,7 +360,7 @@ public:
break; break;
} }
case Constraint::ANGLE: { case Constraint::Type::ANGLE: {
Entity *a = SK.GetEntity(c->entityA); Entity *a = SK.GetEntity(c->entityA);
Entity *b = SK.GetEntity(c->entityB); Entity *b = SK.GetEntity(c->entityB);
@ -411,7 +412,7 @@ public:
break; break;
} }
case Constraint::COMMENT: { case Constraint::Type::COMMENT: {
Style *st = SK.style.FindById(c->GetStyle()); Style *st = SK.style.FindById(c->GetStyle());
writeText(xfrm(c->disp.offset), c->Label(), writeText(xfrm(c->disp.offset), c->Label(),
Style::TextHeight(c->GetStyle()) / SS.GW.scale, Style::TextHeight(c->GetStyle()) / SS.GW.scale,
@ -627,7 +628,7 @@ public:
} }
void writeText(Vector textp, const std::string &text, void writeText(Vector textp, const std::string &text,
double height, double angle, int origin, hStyle hs) { double height, double angle, Style::TextOrigin origin, hStyle hs) {
DRW_Text txt; DRW_Text txt;
assignEntityDefaults(&txt, hs); assignEntityDefaults(&txt, hs);
txt.layer = "text"; txt.layer = "text";
@ -638,15 +639,15 @@ public:
txt.height = height; txt.height = height;
txt.angle = angle; txt.angle = angle;
txt.alignH = DRW_Text::HCenter; txt.alignH = DRW_Text::HCenter;
if(origin & Style::ORIGIN_LEFT) { if((uint32_t)origin & (uint32_t)Style::TextOrigin::LEFT) {
txt.alignH = DRW_Text::HLeft; txt.alignH = DRW_Text::HLeft;
} else if(origin & Style::ORIGIN_RIGHT) { } else if((uint32_t)origin & (uint32_t)Style::TextOrigin::RIGHT) {
txt.alignH = DRW_Text::HRight; txt.alignH = DRW_Text::HRight;
} }
txt.alignV = DRW_Text::VMiddle; txt.alignV = DRW_Text::VMiddle;
if(origin & Style::ORIGIN_TOP) { if((uint32_t)origin & (uint32_t)Style::TextOrigin::TOP) {
txt.alignV = DRW_Text::VTop; txt.alignV = DRW_Text::VTop;
} else if(origin & Style::ORIGIN_BOT) { } else if((uint32_t)origin & (uint32_t)Style::TextOrigin::BOT) {
txt.alignV = DRW_Text::VBaseLine; txt.alignV = DRW_Text::VBaseLine;
} }
dxf->writeText(&txt); dxf->writeText(&txt);
@ -690,26 +691,26 @@ void DxfFileWriter::FinishAndCloseFile() {
bool DxfFileWriter::NeedToOutput(Constraint *c) { bool DxfFileWriter::NeedToOutput(Constraint *c) {
switch(c->type) { switch(c->type) {
case Constraint::PT_PT_DISTANCE: case Constraint::Type::PT_PT_DISTANCE:
case Constraint::PT_LINE_DISTANCE: case Constraint::Type::PT_LINE_DISTANCE:
case Constraint::DIAMETER: case Constraint::Type::DIAMETER:
case Constraint::ANGLE: case Constraint::Type::ANGLE:
case Constraint::COMMENT: case Constraint::Type::COMMENT:
return c->IsVisible(); return c->IsVisible();
} }
return false; return false;
} }
const char *DxfFileWriter::lineTypeName(int stippleType) { const char *DxfFileWriter::lineTypeName(StipplePattern stippleType) {
switch(stippleType) { switch(stippleType) {
case Style::STIPPLE_CONTINUOUS: return "CONTINUOUS"; case StipplePattern::CONTINUOUS: return "CONTINUOUS";
case Style::STIPPLE_DASH: return "DASHED"; case StipplePattern::DASH: return "DASHED";
case Style::STIPPLE_LONG_DASH: return "DASHEDX2"; case StipplePattern::LONG_DASH: return "DASHEDX2";
case Style::STIPPLE_DASH_DOT: return "DASHDOT"; case StipplePattern::DASH_DOT: return "DASHDOT";
case Style::STIPPLE_DASH_DOT_DOT: return "DIVIDE"; case StipplePattern::DASH_DOT_DOT: return "DIVIDE";
case Style::STIPPLE_DOT: return "DOT"; case StipplePattern::DOT: return "DOT";
case Style::STIPPLE_FREEHAND: return "CONTINUOUS"; case StipplePattern::FREEHAND: return "CONTINUOUS";
case Style::STIPPLE_ZIGZAG: return "CONTINUOUS"; case StipplePattern::ZIGZAG: return "CONTINUOUS";
} }
return "CONTINUOUS"; return "CONTINUOUS";
@ -719,7 +720,7 @@ const char *DxfFileWriter::lineTypeName(int stippleType) {
// Routines for EPS output // Routines for EPS output
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static std::string MakeStipplePattern(int pattern, double scale, char delimiter, static std::string MakeStipplePattern(StipplePattern pattern, double scale, char delimiter,
bool inkscapeWorkaround = false) { bool inkscapeWorkaround = false) {
scale /= 2.0; scale /= 2.0;
@ -729,27 +730,27 @@ static std::string MakeStipplePattern(int pattern, double scale, char delimiter,
std::string result; std::string result;
switch(pattern) { switch(pattern) {
case Style::STIPPLE_CONTINUOUS: case StipplePattern::CONTINUOUS:
case Style::STIPPLE_FREEHAND: case StipplePattern::FREEHAND:
case Style::STIPPLE_ZIGZAG: case StipplePattern::ZIGZAG:
return ""; return "";
case Style::STIPPLE_DASH: case StipplePattern::DASH:
result = ssprintf("%.3f_%.3f", scale, scale); result = ssprintf("%.3f_%.3f", scale, scale);
break; break;
case Style::STIPPLE_DASH_DOT: case StipplePattern::DASH_DOT:
result = ssprintf("%.3f_%.3f_%.6f_%.3f", result = ssprintf("%.3f_%.3f_%.6f_%.3f",
scale, scale * 0.5, zero, scale * 0.5); scale, scale * 0.5, zero, scale * 0.5);
break; break;
case Style::STIPPLE_DASH_DOT_DOT: case StipplePattern::DASH_DOT_DOT:
result = ssprintf("%.3f_%.3f_%.6f_%.3f_%.6f_%.3f", result = ssprintf("%.3f_%.3f_%.6f_%.3f_%.6f_%.3f",
scale, scale * 0.5, zero, scale, scale * 0.5, zero,
scale * 0.5, scale * 0.5, zero); scale * 0.5, scale * 0.5, zero);
break; break;
case Style::STIPPLE_DOT: case StipplePattern::DOT:
result = ssprintf("%.6f_%.3f", zero, scale * 0.5); result = ssprintf("%.6f_%.3f", zero, scale * 0.5);
break; break;
case Style::STIPPLE_LONG_DASH: case StipplePattern::LONG_DASH:
result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5); result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5);
break; break;
@ -787,7 +788,7 @@ void EpsFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth,
void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth,
bool filled, RgbaColor fillRgb, hStyle hs) bool filled, RgbaColor fillRgb, hStyle hs)
{ {
int pattern = Style::PatternType(hs); StipplePattern pattern = Style::PatternType(hs);
double stippleScale = MmToPts(Style::StippleScaleMm(hs)); double stippleScale = MmToPts(Style::StippleScaleMm(hs));
fprintf(f, " %.3f setlinewidth\r\n" fprintf(f, " %.3f setlinewidth\r\n"
@ -798,8 +799,7 @@ void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth,
" gsave stroke grestore\r\n", " gsave stroke grestore\r\n",
MmToPts(lineWidth), MmToPts(lineWidth),
strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF(), strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF(),
MakeStipplePattern(pattern, stippleScale, ' ').c_str() MakeStipplePattern(pattern, stippleScale, ' ').c_str());
);
if(filled) { if(filled) {
fprintf(f, " %.3f %.3f %.3f setrgbcolor\r\n" fprintf(f, " %.3f %.3f %.3f setrgbcolor\r\n"
" gsave fill grestore\r\n", " gsave fill grestore\r\n",
@ -1012,7 +1012,7 @@ void PdfFileWriter::FinishAndCloseFile() {
void PdfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, void PdfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth,
bool filled, RgbaColor fillRgb, hStyle hs) bool filled, RgbaColor fillRgb, hStyle hs)
{ {
int pattern = Style::PatternType(hs); StipplePattern pattern = Style::PatternType(hs);
double stippleScale = MmToPts(Style::StippleScaleMm(hs)); double stippleScale = MmToPts(Style::StippleScaleMm(hs));
fprintf(f, "1 J 1 j " // round endcaps and joins fprintf(f, "1 J 1 j " // round endcaps and joins
@ -1113,7 +1113,7 @@ void SvgFileWriter::StartFile() {
for(int i = 0; i < SK.style.n; i++) { for(int i = 0; i < SK.style.n; i++) {
Style *s = &SK.style.elem[i]; Style *s = &SK.style.elem[i];
RgbaColor strokeRgb = Style::Color(s->h, true); RgbaColor strokeRgb = Style::Color(s->h, true);
int pattern = Style::PatternType(s->h); StipplePattern pattern = Style::PatternType(s->h);
double stippleScale = Style::StippleScaleMm(s->h); double stippleScale = Style::StippleScaleMm(s->h);
fprintf(f, ".s%x {\r\n", s->h.v); fprintf(f, ".s%x {\r\n", s->h.v);

View File

@ -213,7 +213,7 @@ Expr *ExprQuaternion::Magnitude() const {
Expr *Expr::From(hParam p) { Expr *Expr::From(hParam p) {
Expr *r = AllocExpr(); Expr *r = AllocExpr();
r->op = PARAM; r->op = Op::PARAM;
r->parh = p; r->parh = p;
return r; return r;
} }
@ -249,12 +249,12 @@ Expr *Expr::From(double v) {
} }
Expr *r = AllocExpr(); Expr *r = AllocExpr();
r->op = CONSTANT; r->op = Op::CONSTANT;
r->v = v; r->v = v;
return r; return r;
} }
Expr *Expr::AnyOp(int newOp, Expr *b) { Expr *Expr::AnyOp(Op newOp, Expr *b) {
Expr *r = AllocExpr(); Expr *r = AllocExpr();
r->op = newOp; r->op = newOp;
r->a = this; r->a = this;
@ -264,24 +264,24 @@ Expr *Expr::AnyOp(int newOp, Expr *b) {
int Expr::Children() const { int Expr::Children() const {
switch(op) { switch(op) {
case PARAM: case Op::PARAM:
case PARAM_PTR: case Op::PARAM_PTR:
case CONSTANT: case Op::CONSTANT:
return 0; return 0;
case PLUS: case Op::PLUS:
case MINUS: case Op::MINUS:
case TIMES: case Op::TIMES:
case DIV: case Op::DIV:
return 2; return 2;
case NEGATE: case Op::NEGATE:
case SQRT: case Op::SQRT:
case SQUARE: case Op::SQUARE:
case SIN: case Op::SIN:
case COS: case Op::COS:
case ASIN: case Op::ASIN:
case ACOS: case Op::ACOS:
return 1; return 1;
default: ssassert(false, "Unexpected operation"); default: ssassert(false, "Unexpected operation");
@ -310,17 +310,17 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
IdList<Param,hParam> *thenTry) const IdList<Param,hParam> *thenTry) const
{ {
Expr *n = AllocExpr(); Expr *n = AllocExpr();
if(op == PARAM) { if(op == Op::PARAM) {
// A param that is referenced by its hParam gets rewritten to go // A param that is referenced by its hParam gets rewritten to go
// straight in to the parameter table with a pointer, or simply // straight in to the parameter table with a pointer, or simply
// into a constant if it's already known. // into a constant if it's already known.
Param *p = firstTry->FindByIdNoOops(parh); Param *p = firstTry->FindByIdNoOops(parh);
if(!p) p = thenTry->FindById(parh); if(!p) p = thenTry->FindById(parh);
if(p->known) { if(p->known) {
n->op = CONSTANT; n->op = Op::CONSTANT;
n->v = p->val; n->v = p->val;
} else { } else {
n->op = PARAM_PTR; n->op = Op::PARAM_PTR;
n->parp = p; n->parp = p;
} }
return n; return n;
@ -335,23 +335,23 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
double Expr::Eval() const { double Expr::Eval() const {
switch(op) { switch(op) {
case PARAM: return SK.GetParam(parh)->val; case Op::PARAM: return SK.GetParam(parh)->val;
case PARAM_PTR: return parp->val; case Op::PARAM_PTR: return parp->val;
case CONSTANT: return v; case Op::CONSTANT: return v;
case PLUS: return a->Eval() + b->Eval(); case Op::PLUS: return a->Eval() + b->Eval();
case MINUS: return a->Eval() - b->Eval(); case Op::MINUS: return a->Eval() - b->Eval();
case TIMES: return a->Eval() * b->Eval(); case Op::TIMES: return a->Eval() * b->Eval();
case DIV: return a->Eval() / b->Eval(); case Op::DIV: return a->Eval() / b->Eval();
case NEGATE: return -(a->Eval()); case Op::NEGATE: return -(a->Eval());
case SQRT: return sqrt(a->Eval()); case Op::SQRT: return sqrt(a->Eval());
case SQUARE: { double r = a->Eval(); return r*r; } case Op::SQUARE: { double r = a->Eval(); return r*r; }
case SIN: return sin(a->Eval()); case Op::SIN: return sin(a->Eval());
case COS: return cos(a->Eval()); case Op::COS: return cos(a->Eval());
case ACOS: return acos(a->Eval()); case Op::ACOS: return acos(a->Eval());
case ASIN: return asin(a->Eval()); case Op::ASIN: return asin(a->Eval());
default: ssassert(false, "Unexpected operation"); default: ssassert(false, "Unexpected operation");
} }
@ -361,38 +361,38 @@ Expr *Expr::PartialWrt(hParam p) const {
Expr *da, *db; Expr *da, *db;
switch(op) { switch(op) {
case PARAM_PTR: return From(p.v == parp->h.v ? 1 : 0); case Op::PARAM_PTR: return From(p.v == parp->h.v ? 1 : 0);
case PARAM: return From(p.v == parh.v ? 1 : 0); case Op::PARAM: return From(p.v == parh.v ? 1 : 0);
case CONSTANT: return From(0.0); case Op::CONSTANT: return From(0.0);
case PLUS: return (a->PartialWrt(p))->Plus(b->PartialWrt(p)); case Op::PLUS: return (a->PartialWrt(p))->Plus(b->PartialWrt(p));
case MINUS: return (a->PartialWrt(p))->Minus(b->PartialWrt(p)); case Op::MINUS: return (a->PartialWrt(p))->Minus(b->PartialWrt(p));
case TIMES: case Op::TIMES:
da = a->PartialWrt(p); da = a->PartialWrt(p);
db = b->PartialWrt(p); db = b->PartialWrt(p);
return (a->Times(db))->Plus(b->Times(da)); return (a->Times(db))->Plus(b->Times(da));
case DIV: case Op::DIV:
da = a->PartialWrt(p); da = a->PartialWrt(p);
db = b->PartialWrt(p); db = b->PartialWrt(p);
return ((da->Times(b))->Minus(a->Times(db)))->Div(b->Square()); return ((da->Times(b))->Minus(a->Times(db)))->Div(b->Square());
case SQRT: case Op::SQRT:
return (From(0.5)->Div(a->Sqrt()))->Times(a->PartialWrt(p)); return (From(0.5)->Div(a->Sqrt()))->Times(a->PartialWrt(p));
case SQUARE: case Op::SQUARE:
return (From(2.0)->Times(a))->Times(a->PartialWrt(p)); return (From(2.0)->Times(a))->Times(a->PartialWrt(p));
case NEGATE: return (a->PartialWrt(p))->Negate(); case Op::NEGATE: return (a->PartialWrt(p))->Negate();
case SIN: return (a->Cos())->Times(a->PartialWrt(p)); case Op::SIN: return (a->Cos())->Times(a->PartialWrt(p));
case COS: return ((a->Sin())->Times(a->PartialWrt(p)))->Negate(); case Op::COS: return ((a->Sin())->Times(a->PartialWrt(p)))->Negate();
case ASIN: case Op::ASIN:
return (From(1)->Div((From(1)->Minus(a->Square()))->Sqrt())) return (From(1)->Div((From(1)->Minus(a->Square()))->Sqrt()))
->Times(a->PartialWrt(p)); ->Times(a->PartialWrt(p));
case ACOS: case Op::ACOS:
return (From(-1)->Div((From(1)->Minus(a->Square()))->Sqrt())) return (From(-1)->Div((From(1)->Minus(a->Square()))->Sqrt()))
->Times(a->PartialWrt(p)); ->Times(a->PartialWrt(p));
@ -402,8 +402,8 @@ Expr *Expr::PartialWrt(hParam p) const {
uint64_t Expr::ParamsUsed() const { uint64_t Expr::ParamsUsed() const {
uint64_t r = 0; uint64_t r = 0;
if(op == PARAM) r |= ((uint64_t)1 << (parh.v % 61)); if(op == Op::PARAM) r |= ((uint64_t)1 << (parh.v % 61));
if(op == PARAM_PTR) r |= ((uint64_t)1 << (parp->h.v % 61)); if(op == Op::PARAM_PTR) r |= ((uint64_t)1 << (parp->h.v % 61));
int c = Children(); int c = Children();
if(c >= 1) r |= a->ParamsUsed(); if(c >= 1) r |= a->ParamsUsed();
@ -412,8 +412,8 @@ uint64_t Expr::ParamsUsed() const {
} }
bool Expr::DependsOn(hParam p) const { bool Expr::DependsOn(hParam p) const {
if(op == PARAM) return (parh.v == p.v); if(op == Op::PARAM) return (parh.v == p.v);
if(op == PARAM_PTR) return (parp->h.v == p.v); if(op == Op::PARAM_PTR) return (parp->h.v == p.v);
int c = Children(); int c = Children();
if(c == 1) return a->DependsOn(p); if(c == 1) return a->DependsOn(p);
@ -433,56 +433,56 @@ Expr *Expr::FoldConstants() {
if(c >= 2) n->b = b->FoldConstants(); if(c >= 2) n->b = b->FoldConstants();
switch(op) { switch(op) {
case PARAM_PTR: case Op::PARAM_PTR:
case PARAM: case Op::PARAM:
case CONSTANT: case Op::CONSTANT:
break; break;
case MINUS: case Op::MINUS:
case TIMES: case Op::TIMES:
case DIV: case Op::DIV:
case PLUS: case Op::PLUS:
// If both ops are known, then we can evaluate immediately // If both ops are known, then we can evaluate immediately
if(n->a->op == CONSTANT && n->b->op == CONSTANT) { if(n->a->op == Op::CONSTANT && n->b->op == Op::CONSTANT) {
double nv = n->Eval(); double nv = n->Eval();
n->op = CONSTANT; n->op = Op::CONSTANT;
n->v = nv; n->v = nv;
break; break;
} }
// x + 0 = 0 + x = x // x + 0 = 0 + x = x
if(op == PLUS && n->b->op == CONSTANT && Tol(n->b->v, 0)) { if(op == Op::PLUS && n->b->op == Op::CONSTANT && Tol(n->b->v, 0)) {
*n = *(n->a); break; *n = *(n->a); break;
} }
if(op == PLUS && n->a->op == CONSTANT && Tol(n->a->v, 0)) { if(op == Op::PLUS && n->a->op == Op::CONSTANT && Tol(n->a->v, 0)) {
*n = *(n->b); break; *n = *(n->b); break;
} }
// 1*x = x*1 = x // 1*x = x*1 = x
if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 1)) { if(op == Op::TIMES && n->b->op == Op::CONSTANT && Tol(n->b->v, 1)) {
*n = *(n->a); break; *n = *(n->a); break;
} }
if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 1)) { if(op == Op::TIMES && n->a->op == Op::CONSTANT && Tol(n->a->v, 1)) {
*n = *(n->b); break; *n = *(n->b); break;
} }
// 0*x = x*0 = 0 // 0*x = x*0 = 0
if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 0)) { if(op == Op::TIMES && n->b->op == Op::CONSTANT && Tol(n->b->v, 0)) {
n->op = CONSTANT; n->v = 0; break; n->op = Op::CONSTANT; n->v = 0; break;
} }
if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 0)) { if(op == Op::TIMES && n->a->op == Op::CONSTANT && Tol(n->a->v, 0)) {
n->op = CONSTANT; n->v = 0; break; n->op = Op::CONSTANT; n->v = 0; break;
} }
break; break;
case SQRT: case Op::SQRT:
case SQUARE: case Op::SQUARE:
case NEGATE: case Op::NEGATE:
case SIN: case Op::SIN:
case COS: case Op::COS:
case ASIN: case Op::ASIN:
case ACOS: case Op::ACOS:
if(n->a->op == CONSTANT) { if(n->a->op == Op::CONSTANT) {
double nv = n->Eval(); double nv = n->Eval();
n->op = CONSTANT; n->op = Op::CONSTANT;
n->v = nv; n->v = nv;
} }
break; break;
@ -493,9 +493,9 @@ Expr *Expr::FoldConstants() {
} }
void Expr::Substitute(hParam oldh, hParam newh) { void Expr::Substitute(hParam oldh, hParam newh) {
ssassert(op != PARAM_PTR, "Expected an expression that refer to params via handles"); ssassert(op != Op::PARAM_PTR, "Expected an expression that refer to params via handles");
if(op == PARAM && parh.v == oldh.v) { if(op == Op::PARAM && parh.v == oldh.v) {
parh = newh; parh = newh;
} }
int c = Children(); int c = Children();
@ -511,14 +511,14 @@ void Expr::Substitute(hParam oldh, hParam newh) {
const hParam Expr::NO_PARAMS = { 0 }; const hParam Expr::NO_PARAMS = { 0 };
const hParam Expr::MULTIPLE_PARAMS = { 1 }; const hParam Expr::MULTIPLE_PARAMS = { 1 };
hParam Expr::ReferencedParams(ParamList *pl) const { hParam Expr::ReferencedParams(ParamList *pl) const {
if(op == PARAM) { if(op == Op::PARAM) {
if(pl->FindByIdNoOops(parh)) { if(pl->FindByIdNoOops(parh)) {
return parh; return parh;
} else { } else {
return NO_PARAMS; return NO_PARAMS;
} }
} }
ssassert(op != PARAM_PTR, "Expected an expression that refer to params via handles"); ssassert(op != Op::PARAM_PTR, "Expected an expression that refer to params via handles");
int c = Children(); int c = Children();
if(c == 0) { if(c == 0) {
@ -550,26 +550,26 @@ std::string Expr::Print() const {
char c; char c;
switch(op) { switch(op) {
case PARAM: return ssprintf("param(%08x)", parh.v); case Op::PARAM: return ssprintf("param(%08x)", parh.v);
case PARAM_PTR: return ssprintf("param(p%08x)", parp->h.v); case Op::PARAM_PTR: return ssprintf("param(p%08x)", parp->h.v);
case CONSTANT: return ssprintf("%.3f", v); case Op::CONSTANT: return ssprintf("%.3f", v);
case PLUS: c = '+'; goto p; case Op::PLUS: c = '+'; goto p;
case MINUS: c = '-'; goto p; case Op::MINUS: c = '-'; goto p;
case TIMES: c = '*'; goto p; case Op::TIMES: c = '*'; goto p;
case DIV: c = '/'; goto p; case Op::DIV: c = '/'; goto p;
p: p:
return "(" + a->Print() + " " + c + " " + b->Print() + ")"; return "(" + a->Print() + " " + c + " " + b->Print() + ")";
break; break;
case NEGATE: return "(- " + a->Print() + ")"; case Op::NEGATE: return "(- " + a->Print() + ")";
case SQRT: return "(sqrt " + a->Print() + ")"; case Op::SQRT: return "(sqrt " + a->Print() + ")";
case SQUARE: return "(square " + a->Print() + ")"; case Op::SQUARE: return "(square " + a->Print() + ")";
case SIN: return "(sin " + a->Print() + ")"; case Op::SIN: return "(sin " + a->Print() + ")";
case COS: return "(cos " + a->Print() + ")"; case Op::COS: return "(cos " + a->Print() + ")";
case ASIN: return "(asin " + a->Print() + ")"; case Op::ASIN: return "(asin " + a->Print() + ")";
case ACOS: return "(acos " + a->Print() + ")"; case Op::ACOS: return "(acos " + a->Print() + ")";
default: ssassert(false, "Unexpected operation"); default: ssassert(false, "Unexpected operation");
} }
@ -623,8 +623,8 @@ void Expr::Consume() {
} }
int Expr::Precedence(Expr *e) { int Expr::Precedence(Expr *e) {
if(e->op == ALL_RESOLVED) return -1; // never want to reduce this marker if(e->op == Op::ALL_RESOLVED) return -1; // never want to reduce this marker
ssassert(e->op == BINARY_OP || e->op == UNARY_OP, "Unexpected operation"); ssassert(e->op == Op::BINARY_OP || e->op == Op::UNARY_OP, "Unexpected operation");
switch(e->c) { switch(e->c) {
case 'q': case 'q':
@ -647,12 +647,12 @@ void Expr::Reduce() {
Expr *op = PopOperator(); Expr *op = PopOperator();
Expr *n; Expr *n;
int o; Op o;
switch(op->c) { switch(op->c) {
case '+': o = PLUS; goto c; case '+': o = Op::PLUS; goto c;
case '-': o = MINUS; goto c; case '-': o = Op::MINUS; goto c;
case '*': o = TIMES; goto c; case '*': o = Op::TIMES; goto c;
case '/': o = DIV; goto c; case '/': o = Op::DIV; goto c;
c: c:
b = PopOperand(); b = PopOperand();
a = PopOperand(); a = PopOperand();
@ -678,30 +678,30 @@ void Expr::ReduceAndPush(Expr *n) {
void Expr::Parse() { void Expr::Parse() {
Expr *e = AllocExpr(); Expr *e = AllocExpr();
e->op = ALL_RESOLVED; e->op = Op::ALL_RESOLVED;
PushOperator(e); PushOperator(e);
for(;;) { for(;;) {
Expr *n = Next(); Expr *n = Next();
if(!n) throw "end of expression unexpected"; if(!n) throw "end of expression unexpected";
if(n->op == CONSTANT) { if(n->op == Op::CONSTANT) {
PushOperand(n); PushOperand(n);
Consume(); Consume();
} else if(n->op == PAREN && n->c == '(') { } else if(n->op == Op::PAREN && n->c == '(') {
Consume(); Consume();
Parse(); Parse();
n = Next(); n = Next();
if(n->op != PAREN || n->c != ')') throw "expected: )"; if(n->op != Op::PAREN || n->c != ')') throw "expected: )";
Consume(); Consume();
} else if(n->op == UNARY_OP) { } else if(n->op == Op::UNARY_OP) {
PushOperator(n); PushOperator(n);
Consume(); Consume();
continue; continue;
} else if(n->op == BINARY_OP && n->c == '-') { } else if(n->op == Op::BINARY_OP && n->c == '-') {
// The minus sign is special, because it might be binary or // The minus sign is special, because it might be binary or
// unary, depending on context. // unary, depending on context.
n->op = UNARY_OP; n->op = Op::UNARY_OP;
n->c = 'n'; n->c = 'n';
PushOperator(n); PushOperator(n);
Consume(); Consume();
@ -711,7 +711,7 @@ void Expr::Parse() {
} }
n = Next(); n = Next();
if(n && n->op == BINARY_OP) { if(n && n->op == Op::BINARY_OP) {
ReduceAndPush(n); ReduceAndPush(n);
Consume(); Consume();
} else { } else {
@ -719,7 +719,7 @@ void Expr::Parse() {
} }
} }
while(TopOperator()->op != ALL_RESOLVED) { while(TopOperator()->op != Op::ALL_RESOLVED) {
Reduce(); Reduce();
} }
PopOperator(); // discard the ALL_RESOLVED marker PopOperator(); // discard the ALL_RESOLVED marker
@ -740,7 +740,7 @@ void Expr::Lex(const char *in) {
} }
number[len++] = '\0'; number[len++] = '\0';
Expr *e = AllocExpr(); Expr *e = AllocExpr();
e->op = CONSTANT; e->op = Op::CONSTANT;
e->v = atof(number); e->v = atof(number);
Unparsed[UnparsedCnt++] = e; Unparsed[UnparsedCnt++] = e;
} else if(isalpha(c) || c == '_') { } else if(isalpha(c) || c == '_') {
@ -754,16 +754,16 @@ void Expr::Lex(const char *in) {
Expr *e = AllocExpr(); Expr *e = AllocExpr();
if(strcmp(name, "sqrt")==0) { if(strcmp(name, "sqrt")==0) {
e->op = UNARY_OP; e->op = Op::UNARY_OP;
e->c = 'q'; e->c = 'q';
} else if(strcmp(name, "cos")==0) { } else if(strcmp(name, "cos")==0) {
e->op = UNARY_OP; e->op = Op::UNARY_OP;
e->c = 'c'; e->c = 'c';
} else if(strcmp(name, "sin")==0) { } else if(strcmp(name, "sin")==0) {
e->op = UNARY_OP; e->op = Op::UNARY_OP;
e->c = 's'; e->c = 's';
} else if(strcmp(name, "pi")==0) { } else if(strcmp(name, "pi")==0) {
e->op = CONSTANT; e->op = Op::CONSTANT;
e->v = PI; e->v = PI;
} else { } else {
throw "unknown name"; throw "unknown name";
@ -771,7 +771,7 @@ void Expr::Lex(const char *in) {
Unparsed[UnparsedCnt++] = e; Unparsed[UnparsedCnt++] = e;
} else if(strchr("+-*/()", c)) { } else if(strchr("+-*/()", c)) {
Expr *e = AllocExpr(); Expr *e = AllocExpr();
e->op = (c == '(' || c == ')') ? PAREN : BINARY_OP; e->op = (c == '(' || c == ')') ? Op::PAREN : Op::BINARY_OP;
e->c = c; e->c = c;
Unparsed[UnparsedCnt++] = e; Unparsed[UnparsedCnt++] = e;
in++; in++;

View File

@ -13,7 +13,7 @@ class Expr;
class Expr { class Expr {
public: public:
enum { enum class Op : uint32_t {
// A parameter, by the hParam handle // A parameter, by the hParam handle
PARAM = 0, PARAM = 0,
// A parameter, by a pointer straight in to the param table (faster, // A parameter, by a pointer straight in to the param table (faster,
@ -45,7 +45,7 @@ public:
UNARY_OP = 1003 UNARY_OP = 1003
}; };
int op; Op op;
Expr *a; Expr *a;
union { union {
double v; double v;
@ -58,7 +58,7 @@ public:
}; };
Expr() { } Expr() { }
Expr(double val) : op(CONSTANT) { v = val; } Expr(double val) : op(Op::CONSTANT) { v = val; }
static inline Expr *AllocExpr() static inline Expr *AllocExpr()
{ return (Expr *)AllocTemporary(sizeof(Expr)); } { return (Expr *)AllocTemporary(sizeof(Expr)); }
@ -66,19 +66,19 @@ public:
static Expr *From(hParam p); static Expr *From(hParam p);
static Expr *From(double v); static Expr *From(double v);
Expr *AnyOp(int op, Expr *b); Expr *AnyOp(Op op, Expr *b);
inline Expr *Plus (Expr *b_) { return AnyOp(PLUS, b_); } inline Expr *Plus (Expr *b_) { return AnyOp(Op::PLUS, b_); }
inline Expr *Minus(Expr *b_) { return AnyOp(MINUS, b_); } inline Expr *Minus(Expr *b_) { return AnyOp(Op::MINUS, b_); }
inline Expr *Times(Expr *b_) { return AnyOp(TIMES, b_); } inline Expr *Times(Expr *b_) { return AnyOp(Op::TIMES, b_); }
inline Expr *Div (Expr *b_) { return AnyOp(DIV, b_); } inline Expr *Div (Expr *b_) { return AnyOp(Op::DIV, b_); }
inline Expr *Negate() { return AnyOp(NEGATE, NULL); } inline Expr *Negate() { return AnyOp(Op::NEGATE, NULL); }
inline Expr *Sqrt () { return AnyOp(SQRT, NULL); } inline Expr *Sqrt () { return AnyOp(Op::SQRT, NULL); }
inline Expr *Square() { return AnyOp(SQUARE, NULL); } inline Expr *Square() { return AnyOp(Op::SQUARE, NULL); }
inline Expr *Sin () { return AnyOp(SIN, NULL); } inline Expr *Sin () { return AnyOp(Op::SIN, NULL); }
inline Expr *Cos () { return AnyOp(COS, NULL); } inline Expr *Cos () { return AnyOp(Op::COS, NULL); }
inline Expr *ASin () { return AnyOp(ASIN, NULL); } inline Expr *ASin () { return AnyOp(Op::ASIN, NULL); }
inline Expr *ACos () { return AnyOp(ACOS, NULL); } inline Expr *ACos () { return AnyOp(Op::ACOS, NULL); }
Expr *PartialWrt(hParam p) const; Expr *PartialWrt(hParam p) const;
double Eval() const; double Eval() const;

View File

@ -41,8 +41,8 @@ hGroup SolveSpaceUI::CreateDefaultDrawingGroup() {
// And an empty group, for the first stuff the user draws. // And an empty group, for the first stuff the user draws.
g.visible = true; g.visible = true;
g.name = "sketch-in-plane"; g.name = "sketch-in-plane";
g.type = Group::DRAWING_WORKPLANE; g.type = Group::Type::DRAWING_WORKPLANE;
g.subtype = Group::WORKPLANE_BY_POINT_ORTHO; g.subtype = Group::Subtype::WORKPLANE_BY_POINT_ORTHO;
g.order = 1; g.order = 1;
g.predef.q = Quaternion::From(1, 0, 0, 0); g.predef.q = Quaternion::From(1, 0, 0, 0);
hRequest hr = Request::HREQUEST_REFERENCE_XY; hRequest hr = Request::HREQUEST_REFERENCE_XY;
@ -59,7 +59,7 @@ void SolveSpaceUI::NewFile() {
Group g = {}; Group g = {};
g.visible = true; g.visible = true;
g.name = "#references"; g.name = "#references";
g.type = Group::DRAWING_3D; g.type = Group::Type::DRAWING_3D;
g.order = 0; g.order = 0;
g.h = Group::HGROUP_REFERENCES; g.h = Group::HGROUP_REFERENCES;
SK.group.Add(&g); SK.group.Add(&g);
@ -67,7 +67,7 @@ void SolveSpaceUI::NewFile() {
// Let's create three two-d coordinate systems, for the coordinate // Let's create three two-d coordinate systems, for the coordinate
// planes; these are our references, present in every sketch. // planes; these are our references, present in every sketch.
Request r = {}; Request r = {};
r.type = Request::WORKPLANE; r.type = Request::Type::WORKPLANE;
r.group = Group::HGROUP_REFERENCES; r.group = Group::HGROUP_REFERENCES;
r.workplane = Entity::FREE_IN_3D; r.workplane = Entity::FREE_IN_3D;
@ -260,7 +260,7 @@ bool SolveSpaceUI::SaveToFile(const std::string &filename) {
// the linkFileRel for our possibly-new filename. // the linkFileRel for our possibly-new filename.
SS.ScheduleShowTW(); SS.ScheduleShowTW();
SS.ReloadAllImported(); SS.ReloadAllImported();
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
fh = ssfopen(filename, "wb"); fh = ssfopen(filename, "wb");
if(!fh) { if(!fh) {
@ -460,7 +460,7 @@ bool SolveSpaceUI::LoadFromFile(const std::string &filename) {
} else if(strcmp(line, "AddGroup")==0) { } else if(strcmp(line, "AddGroup")==0) {
// legacy files have a spurious dependency between linked groups // legacy files have a spurious dependency between linked groups
// and their parent groups, remove // and their parent groups, remove
if(sv.g.type == Group::LINKED) if(sv.g.type == Group::Type::LINKED)
sv.g.opA.v = 0; sv.g.opA.v = 0;
SK.group.Add(&(sv.g)); SK.group.Add(&(sv.g));
@ -785,7 +785,7 @@ bool SolveSpaceUI::ReloadAllImported(bool canCancel)
int i; int i;
for(i = 0; i < SK.group.n; i++) { for(i = 0; i < SK.group.n; i++) {
Group *g = &(SK.group.elem[i]); Group *g = &(SK.group.elem[i]);
if(g->type != Group::LINKED) continue; if(g->type != Group::Type::LINKED) continue;
if(isalpha(g->linkFile[0]) && g->linkFile[1] == ':') { if(isalpha(g->linkFile[0]) && g->linkFile[1] == ':') {
// Make sure that g->linkFileRel always contains a relative path // Make sure that g->linkFileRel always contains a relative path

View File

@ -128,9 +128,9 @@ bool SolveSpaceUI::PruneConstraints(hGroup hg) {
} }
(deleted.constraints)++; (deleted.constraints)++;
if(c->type != Constraint::POINTS_COINCIDENT && if(c->type != Constraint::Type::POINTS_COINCIDENT &&
c->type != Constraint::HORIZONTAL && c->type != Constraint::Type::HORIZONTAL &&
c->type != Constraint::VERTICAL) c->type != Constraint::Type::VERTICAL)
{ {
(deleted.nonTrivialConstraints)++; (deleted.nonTrivialConstraints)++;
} }
@ -141,7 +141,7 @@ bool SolveSpaceUI::PruneConstraints(hGroup hg) {
return false; return false;
} }
void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForBBox) { void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox) {
int first, last, i, j; int first, last, i, j;
SK.groupOrder.Clear(); SK.groupOrder.Clear();
@ -153,7 +153,7 @@ void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForB
}); });
switch(type) { switch(type) {
case GENERATE_DIRTY: { case Generate::DIRTY: {
first = INT_MAX; first = INT_MAX;
last = 0; last = 0;
@ -178,17 +178,17 @@ void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForB
break; break;
} }
case GENERATE_ALL: case Generate::ALL:
first = 0; first = 0;
last = INT_MAX; last = INT_MAX;
break; break;
case GENERATE_REGEN: case Generate::REGEN:
first = -1; first = -1;
last = -1; last = -1;
break; break;
case GENERATE_UNTIL_ACTIVE: { case Generate::UNTIL_ACTIVE: {
for(i = 0; i < SK.groupOrder.n; i++) { for(i = 0; i < SK.groupOrder.n; i++) {
if(SK.groupOrder.elem[i].v == SS.GW.activeGroup.v) if(SK.groupOrder.elem[i].v == SS.GW.activeGroup.v)
break; break;
@ -298,7 +298,7 @@ void SolveSpaceUI::GenerateAll(GenerateType type, bool andFindFree, bool genForB
if(g->h.v == Group::HGROUP_REFERENCES.v) { if(g->h.v == Group::HGROUP_REFERENCES.v) {
ForceReferences(); ForceReferences();
g->solved.how = System::SOLVED_OKAY; g->solved.how = SolveResult::OKAY;
g->clean = true; g->clean = true;
} else { } else {
if(i >= first && i <= last) { if(i >= first && i <= last) {
@ -447,14 +447,14 @@ void SolveSpaceUI::MarkDraggedParams() {
Entity *pt = SK.entity.FindByIdNoOops(hp); Entity *pt = SK.entity.FindByIdNoOops(hp);
if(pt) { if(pt) {
switch(pt->type) { switch(pt->type) {
case Entity::POINT_N_TRANS: case Entity::Type::POINT_N_TRANS:
case Entity::POINT_IN_3D: case Entity::Type::POINT_IN_3D:
sys.dragged.Add(&(pt->param[0])); sys.dragged.Add(&(pt->param[0]));
sys.dragged.Add(&(pt->param[1])); sys.dragged.Add(&(pt->param[1]));
sys.dragged.Add(&(pt->param[2])); sys.dragged.Add(&(pt->param[2]));
break; break;
case Entity::POINT_IN_2D: case Entity::Type::POINT_IN_2D:
sys.dragged.Add(&(pt->param[0])); sys.dragged.Add(&(pt->param[0]));
sys.dragged.Add(&(pt->param[1])); sys.dragged.Add(&(pt->param[1]));
break; break;
@ -466,7 +466,7 @@ void SolveSpaceUI::MarkDraggedParams() {
if(circ) { if(circ) {
Entity *dist = SK.GetEntity(circ->distance); Entity *dist = SK.GetEntity(circ->distance);
switch(dist->type) { switch(dist->type) {
case Entity::DISTANCE: case Entity::Type::DISTANCE:
sys.dragged.Add(&(dist->param[0])); sys.dragged.Add(&(dist->param[0]));
break; break;
} }
@ -476,7 +476,7 @@ void SolveSpaceUI::MarkDraggedParams() {
Entity *norm = SK.entity.FindByIdNoOops(SS.GW.pending.normal); Entity *norm = SK.entity.FindByIdNoOops(SS.GW.pending.normal);
if(norm) { if(norm) {
switch(norm->type) { switch(norm->type) {
case Entity::NORMAL_IN_3D: case Entity::Type::NORMAL_IN_3D:
sys.dragged.Add(&(norm->param[0])); sys.dragged.Add(&(norm->param[0]));
sys.dragged.Add(&(norm->param[1])); sys.dragged.Add(&(norm->param[1]));
sys.dragged.Add(&(norm->param[2])); sys.dragged.Add(&(norm->param[2]));
@ -513,10 +513,10 @@ void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
MarkDraggedParams(); MarkDraggedParams();
g->solved.remove.Clear(); g->solved.remove.Clear();
int how = sys.Solve(g, &(g->solved.dof), SolveResult how = sys.Solve(g, &(g->solved.dof),
&(g->solved.remove), true, andFindFree); &(g->solved.remove), true, andFindFree);
bool isOkay = how == System::SOLVED_OKAY || bool isOkay = how == SolveResult::OKAY ||
(g->allowRedundant && how == System::REDUNDANT_OKAY); (g->allowRedundant && how == SolveResult::REDUNDANT_OKAY);
if(!isOkay || (isOkay && !g->IsSolvedOkay())) if(!isOkay || (isOkay && !g->IsSolvedOkay()))
{ {
TextWindow::ReportHowGroupSolved(g->h); TextWindow::ReportHowGroupSolved(g->h);

View File

@ -115,18 +115,18 @@ void ssglPoint(Vector p, double pixelSize)
} }
void ssglStippledLine(Vector a, Vector b, double width, void ssglStippledLine(Vector a, Vector b, double width,
int stippleType, double stippleScale, bool maybeFat) StipplePattern stippleType, double stippleScale, bool maybeFat)
{ {
const char *stipplePattern; const char *stipplePattern;
switch(stippleType) { switch(stippleType) {
case Style::STIPPLE_CONTINUOUS: ssglLine(a, b, width, maybeFat); return; case StipplePattern::CONTINUOUS: ssglLine(a, b, width, maybeFat); return;
case Style::STIPPLE_DASH: stipplePattern = "- "; break; case StipplePattern::DASH: stipplePattern = "- "; break;
case Style::STIPPLE_LONG_DASH: stipplePattern = "_ "; break; case StipplePattern::LONG_DASH: stipplePattern = "_ "; break;
case Style::STIPPLE_DASH_DOT: stipplePattern = "-."; break; case StipplePattern::DASH_DOT: stipplePattern = "-."; break;
case Style::STIPPLE_DASH_DOT_DOT: stipplePattern = "-.."; break; case StipplePattern::DASH_DOT_DOT: stipplePattern = "-.."; break;
case Style::STIPPLE_DOT: stipplePattern = "."; break; case StipplePattern::DOT: stipplePattern = "."; break;
case Style::STIPPLE_FREEHAND: stipplePattern = "~"; break; case StipplePattern::FREEHAND: stipplePattern = "~"; break;
case Style::STIPPLE_ZIGZAG: stipplePattern = "~__"; break; case StipplePattern::ZIGZAG: stipplePattern = "~__"; break;
default: ssassert(false, "Unexpected stipple pattern"); default: ssassert(false, "Unexpected stipple pattern");
} }
ssglStippledLine(a, b, width, stipplePattern, stippleScale, maybeFat); ssglStippledLine(a, b, width, stipplePattern, stippleScale, maybeFat);
@ -451,7 +451,7 @@ void ssglDebugPolygon(SPolygon *p)
void ssglDrawEdges(SEdgeList *el, bool endpointsToo, hStyle hs) void ssglDrawEdges(SEdgeList *el, bool endpointsToo, hStyle hs)
{ {
double lineWidth = Style::Width(hs); double lineWidth = Style::Width(hs);
int stippleType = Style::PatternType(hs); StipplePattern stippleType = Style::PatternType(hs);
double stippleScale = Style::StippleScaleMm(hs); double stippleScale = Style::StippleScaleMm(hs);
ssglLineWidth(float(lineWidth)); ssglLineWidth(float(lineWidth));
ssglColorRGB(Style::Color(hs)); ssglColorRGB(Style::Color(hs));
@ -476,7 +476,7 @@ void ssglDrawEdges(SEdgeList *el, bool endpointsToo, hStyle hs)
void ssglDrawOutlines(SOutlineList *sol, Vector projDir, hStyle hs) void ssglDrawOutlines(SOutlineList *sol, Vector projDir, hStyle hs)
{ {
double lineWidth = Style::Width(hs); double lineWidth = Style::Width(hs);
int stippleType = Style::PatternType(hs); StipplePattern stippleType = Style::PatternType(hs);
double stippleScale = Style::StippleScaleMm(hs); double stippleScale = Style::StippleScaleMm(hs);
ssglLineWidth((float)lineWidth); ssglLineWidth((float)lineWidth);
ssglColorRGB(Style::Color(hs)); ssglColorRGB(Style::Color(hs));

View File

@ -21,151 +21,150 @@
#define S SHIFT_MASK #define S SHIFT_MASK
#define C CTRL_MASK #define C CTRL_MASK
#define F(k) (FUNCTION_KEY_BASE+(k)) #define F(k) (FUNCTION_KEY_BASE+(k))
#define TN MENU_ITEM_NORMAL #define TN MenuKind::NORMAL
#define TC MENU_ITEM_CHECK #define TC MenuKind::CHECK
#define TR MENU_ITEM_RADIO #define TR MenuKind::RADIO
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = { const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
//level //level
// label id accel ty fn // label id accel ty fn
{ 0, "&File", 0, 0, TN, NULL }, { 0, "&File", Command::NONE, 0, TN, NULL },
{ 1, "&New", MNU_NEW, C|'N', TN, mFile }, { 1, "&New", Command::NEW, C|'N', TN, mFile },
{ 1, "&Open...", MNU_OPEN, C|'O', TN, mFile }, { 1, "&Open...", Command::OPEN, C|'O', TN, mFile },
{ 1, "Open &Recent", MNU_OPEN_RECENT, 0, TN, mFile }, { 1, "Open &Recent", Command::OPEN_RECENT, 0, TN, mFile },
{ 1, "&Save", MNU_SAVE, C|'S', TN, mFile }, { 1, "&Save", Command::SAVE, C|'S', TN, mFile },
{ 1, "Save &As...", MNU_SAVE_AS, 0, TN, mFile }, { 1, "Save &As...", Command::SAVE_AS, 0, TN, mFile },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Export &Image...", MNU_EXPORT_PNG, 0, TN, mFile }, { 1, "Export &Image...", Command::EXPORT_PNG, 0, TN, mFile },
{ 1, "Export 2d &View...", MNU_EXPORT_VIEW, 0, TN, mFile }, { 1, "Export 2d &View...", Command::EXPORT_VIEW, 0, TN, mFile },
{ 1, "Export 2d &Section...", MNU_EXPORT_SECTION, 0, TN, mFile }, { 1, "Export 2d &Section...", Command::EXPORT_SECTION, 0, TN, mFile },
{ 1, "Export 3d &Wireframe...", MNU_EXPORT_WIREFRAME, 0, TN, mFile }, { 1, "Export 3d &Wireframe...", Command::EXPORT_WIREFRAME, 0, TN, mFile },
{ 1, "Export Triangle &Mesh...", MNU_EXPORT_MESH, 0, TN, mFile }, { 1, "Export Triangle &Mesh...", Command::EXPORT_MESH, 0, TN, mFile },
{ 1, "Export &Surfaces...", MNU_EXPORT_SURFACES,0, TN, mFile }, { 1, "Export &Surfaces...", Command::EXPORT_SURFACES, 0, TN, mFile },
{ 1, "Im&port...", MNU_IMPORT ,0, TN, mFile }, { 1, "Im&port...", Command::IMPORT, 0, TN, mFile },
#ifndef __APPLE__ #ifndef __APPLE__
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "E&xit", MNU_EXIT, C|'Q', TN, mFile }, { 1, "E&xit", Command::EXIT, C|'Q', TN, mFile },
#endif #endif
{ 0, "&Edit", 0, 0, TN, NULL }, { 0, "&Edit", Command::NONE, 0, TN, NULL },
{ 1, "&Undo", MNU_UNDO, C|'Z', TN, mEdit }, { 1, "&Undo", Command::UNDO, C|'Z', TN, mEdit },
{ 1, "&Redo", MNU_REDO, C|'Y', TN, mEdit }, { 1, "&Redo", Command::REDO, C|'Y', TN, mEdit },
{ 1, "Re&generate All", MNU_REGEN_ALL, ' ', TN, mEdit }, { 1, "Re&generate All", Command::REGEN_ALL, ' ', TN, mEdit },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Snap Selection to &Grid", MNU_SNAP_TO_GRID, '.', TN, mEdit }, { 1, "Snap Selection to &Grid", Command::SNAP_TO_GRID, '.', TN, mEdit },
{ 1, "Rotate Imported &90°", MNU_ROTATE_90, '9', TN, mEdit }, { 1, "Rotate Imported &90°", Command::ROTATE_90, '9', TN, mEdit },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Cu&t", MNU_CUT, C|'X', TN, mClip }, { 1, "Cu&t", Command::CUT, C|'X', TN, mClip },
{ 1, "&Copy", MNU_COPY, C|'C', TN, mClip }, { 1, "&Copy", Command::COPY, C|'C', TN, mClip },
{ 1, "&Paste", MNU_PASTE, C|'V', TN, mClip }, { 1, "&Paste", Command::PASTE, C|'V', TN, mClip },
{ 1, "Paste &Transformed...", MNU_PASTE_TRANSFORM,C|'T', TN, mClip }, { 1, "Paste &Transformed...", Command::PASTE_TRANSFORM, C|'T', TN, mClip },
{ 1, "&Delete", MNU_DELETE, DEL, TN, mClip }, { 1, "&Delete", Command::DELETE, DEL, TN, mClip },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Select &Edge Chain", MNU_SELECT_CHAIN, C|'E', TN, mEdit }, { 1, "Select &Edge Chain", Command::SELECT_CHAIN, C|'E', TN, mEdit },
{ 1, "Select &All", MNU_SELECT_ALL, C|'A', TN, mEdit }, { 1, "Select &All", Command::SELECT_ALL, C|'A', TN, mEdit },
{ 1, "&Unselect All", MNU_UNSELECT_ALL, ESC, TN, mEdit }, { 1, "&Unselect All", Command::UNSELECT_ALL, ESC, TN, mEdit },
{ 0, "&View", 0, 0, TN, NULL }, { 0, "&View", Command::NONE, 0, TN, NULL },
{ 1, "Zoom &In", MNU_ZOOM_IN, '+', TN, mView }, { 1, "Zoom &In", Command::ZOOM_IN, '+', TN, mView },
{ 1, "Zoom &Out", MNU_ZOOM_OUT, '-', TN, mView }, { 1, "Zoom &Out", Command::ZOOM_OUT, '-', TN, mView },
{ 1, "Zoom To &Fit", MNU_ZOOM_TO_FIT, 'F', TN, mView }, { 1, "Zoom To &Fit", Command::ZOOM_TO_FIT, 'F', TN, mView },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Align View to &Workplane", MNU_ONTO_WORKPLANE, 'W', TN, mView }, { 1, "Align View to &Workplane", Command::ONTO_WORKPLANE, 'W', TN, mView },
{ 1, "Nearest &Ortho View", MNU_NEAREST_ORTHO, F(2), TN, mView }, { 1, "Nearest &Ortho View", Command::NEAREST_ORTHO, F(2), TN, mView },
{ 1, "Nearest &Isometric View", MNU_NEAREST_ISO, F(3), TN, mView }, { 1, "Nearest &Isometric View", Command::NEAREST_ISO, F(3), TN, mView },
{ 1, "&Center View At Point", MNU_CENTER_VIEW, F(4), TN, mView }, { 1, "&Center View At Point", Command::CENTER_VIEW, F(4), TN, mView },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Show Snap &Grid", MNU_SHOW_GRID, '>', TC, mView }, { 1, "Show Snap &Grid", Command::SHOW_GRID, '>', TC, mView },
{ 1, "Use &Perspective Projection", MNU_PERSPECTIVE_PROJ,'`', TC, mView }, { 1, "Use &Perspective Projection", Command::PERSPECTIVE_PROJ, '`', TC, mView },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
#if defined(__APPLE__) #if defined(__APPLE__)
{ 1, "Show Menu &Bar", MNU_SHOW_MENU_BAR, C|F(12), TC, mView }, { 1, "Show Menu &Bar", Command::SHOW_MENU_BAR, C|F(12), TC, mView },
#endif #endif
{ 1, "Show &Toolbar", MNU_SHOW_TOOLBAR, 0, TC, mView }, { 1, "Show &Toolbar", Command::SHOW_TOOLBAR, 0, TC, mView },
{ 1, "Show Property Bro&wser", MNU_SHOW_TEXT_WND, '\t', TC, mView }, { 1, "Show Property Bro&wser", Command::SHOW_TEXT_WND, '\t', TC, mView },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Dimensions in &Inches", MNU_UNITS_INCHES, 0, TR, mView }, { 1, "Dimensions in &Inches", Command::UNITS_INCHES, 0, TR, mView },
{ 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, TR, mView }, { 1, "Dimensions in &Millimeters", Command::UNITS_MM, 0, TR, mView },
#if defined(HAVE_GTK) || defined(__APPLE__) #if defined(HAVE_GTK) || defined(__APPLE__)
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Full Screen", MNU_FULL_SCREEN, C|F(11), TC, mView }, { 1, "&Full Screen", Command::FULL_SCREEN, C|F(11), TC, mView },
#endif #endif
{ 0, "&New Group", 0, 0, TN, NULL }, { 0, "&New Group", Command::NONE, 0, TN, NULL },
{ 1, "Sketch In &3d", MNU_GROUP_3D, S|'3', TN, mGrp }, { 1, "Sketch In &3d", Command::GROUP_3D, S|'3', TN, mGrp },
{ 1, "Sketch In New &Workplane", MNU_GROUP_WRKPL, S|'W', TN, mGrp }, { 1, "Sketch In New &Workplane", Command::GROUP_WRKPL, S|'W', TN, mGrp },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Step &Translating", MNU_GROUP_TRANS, S|'T', TN, mGrp }, { 1, "Step &Translating", Command::GROUP_TRANS, S|'T', TN, mGrp },
{ 1, "Step &Rotating", MNU_GROUP_ROT, S|'R', TN, mGrp }, { 1, "Step &Rotating", Command::GROUP_ROT, S|'R', TN, mGrp },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "E&xtrude", MNU_GROUP_EXTRUDE, S|'X', TN, mGrp }, { 1, "E&xtrude", Command::GROUP_EXTRUDE, S|'X', TN, mGrp },
{ 1, "&Lathe", MNU_GROUP_LATHE, S|'L', TN, mGrp }, { 1, "&Lathe", Command::GROUP_LATHE, S|'L', TN, mGrp },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Link / Assemble...", MNU_GROUP_LINK, S|'I', TN, mGrp }, { 1, "Link / Assemble...", Command::GROUP_LINK, S|'I', TN, mGrp },
{ 1, "Link Recent", MNU_GROUP_RECENT, 0, TN, mGrp }, { 1, "Link Recent", Command::GROUP_RECENT, 0, TN, mGrp },
{ 0, "&Sketch", 0, 0, TN, NULL }, { 0, "&Sketch", Command::NONE, 0, TN, NULL },
{ 1, "In &Workplane", MNU_SEL_WORKPLANE, '2', TR, mReq }, { 1, "In &Workplane", Command::SEL_WORKPLANE, '2', TR, mReq },
{ 1, "Anywhere In &3d", MNU_FREE_IN_3D, '3', TR, mReq }, { 1, "Anywhere In &3d", Command::FREE_IN_3D, '3', TR, mReq },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Datum &Point", MNU_DATUM_POINT, 'P', TN, mReq }, { 1, "Datum &Point", Command::DATUM_POINT, 'P', TN, mReq },
{ 1, "&Workplane", MNU_WORKPLANE, 0, TN, mReq }, { 1, "&Workplane", Command::WORKPLANE, 0, TN, mReq },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Line &Segment", MNU_LINE_SEGMENT, 'S', TN, mReq }, { 1, "Line &Segment", Command::LINE_SEGMENT, 'S', TN, mReq },
{ 1, "C&onstruction Line Segment", MNU_CONSTR_SEGMENT, S|'S', TN, mReq }, { 1, "C&onstruction Line Segment", Command::CONSTR_SEGMENT, S|'S', TN, mReq },
{ 1, "&Rectangle", MNU_RECTANGLE, 'R', TN, mReq }, { 1, "&Rectangle", Command::RECTANGLE, 'R', TN, mReq },
{ 1, "&Circle", MNU_CIRCLE, 'C', TN, mReq }, { 1, "&Circle", Command::CIRCLE, 'C', TN, mReq },
{ 1, "&Arc of a Circle", MNU_ARC, 'A', TN, mReq }, { 1, "&Arc of a Circle", Command::ARC, 'A', TN, mReq },
{ 1, "&Bezier Cubic Spline", MNU_CUBIC, 'B', TN, mReq }, { 1, "&Bezier Cubic Spline", Command::CUBIC, 'B', TN, mReq },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Text in TrueType Font", MNU_TTF_TEXT, 'T', TN, mReq }, { 1, "&Text in TrueType Font", Command::TTF_TEXT, 'T', TN, mReq },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "To&ggle Construction", MNU_CONSTRUCTION, 'G', TN, mReq }, { 1, "To&ggle Construction", Command::CONSTRUCTION, 'G', TN, mReq },
{ 1, "Tangent &Arc at Point", MNU_TANGENT_ARC, S|'A', TN, mReq }, { 1, "Tangent &Arc at Point", Command::TANGENT_ARC, S|'A', TN, mReq },
{ 1, "Split Curves at &Intersection", MNU_SPLIT_CURVES, 'I', TN, mReq }, { 1, "Split Curves at &Intersection", Command::SPLIT_CURVES, 'I', TN, mReq },
{ 0, "&Constrain", 0, 0, TN, NULL }, { 0, "&Constrain", Command::NONE, 0, TN, NULL },
{ 1, "&Distance / Diameter", MNU_DISTANCE_DIA, 'D', TN, mCon }, { 1, "&Distance / Diameter", Command::DISTANCE_DIA, 'D', TN, mCon },
{ 1, "Re&ference Dimension", MNU_REF_DISTANCE, S|'D', TN, mCon }, { 1, "Re&ference Dimension", Command::REF_DISTANCE, S|'D', TN, mCon },
{ 1, "A&ngle", MNU_ANGLE, 'N', TN, mCon }, { 1, "A&ngle", Command::ANGLE, 'N', TN, mCon },
{ 1, "Reference An&gle", MNU_REF_ANGLE, S|'N', TN, mCon }, { 1, "Reference An&gle", Command::REF_ANGLE, S|'N', TN, mCon },
{ 1, "Other S&upplementary Angle", MNU_OTHER_ANGLE, 'U', TN, mCon }, { 1, "Other S&upplementary Angle", Command::OTHER_ANGLE, 'U', TN, mCon },
{ 1, "Toggle R&eference Dim", MNU_REFERENCE, 'E', TN, mCon }, { 1, "Toggle R&eference Dim", Command::REFERENCE, 'E', TN, mCon },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Horizontal", MNU_HORIZONTAL, 'H', TN, mCon }, { 1, "&Horizontal", Command::HORIZONTAL, 'H', TN, mCon },
{ 1, "&Vertical", MNU_VERTICAL, 'V', TN, mCon }, { 1, "&Vertical", Command::VERTICAL, 'V', TN, mCon },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&On Point / Curve / Plane", MNU_ON_ENTITY, 'O', TN, mCon }, { 1, "&On Point / Curve / Plane", Command::ON_ENTITY, 'O', TN, mCon },
{ 1, "E&qual Length / Radius / Angle", MNU_EQUAL, 'Q', TN, mCon }, { 1, "E&qual Length / Radius / Angle", Command::EQUAL, 'Q', TN, mCon },
{ 1, "Length Ra&tio", MNU_RATIO, 'Z', TN, mCon }, { 1, "Length Ra&tio", Command::RATIO, 'Z', TN, mCon },
{ 1, "Length Diff&erence", MNU_DIFFERENCE, 'J', TN, mCon }, { 1, "Length Diff&erence", Command::DIFFERENCE, 'J', TN, mCon },
{ 1, "At &Midpoint", MNU_AT_MIDPOINT, 'M', TN, mCon }, { 1, "At &Midpoint", Command::AT_MIDPOINT, 'M', TN, mCon },
{ 1, "S&ymmetric", MNU_SYMMETRIC, 'Y', TN, mCon }, { 1, "S&ymmetric", Command::SYMMETRIC, 'Y', TN, mCon },
{ 1, "Para&llel / Tangent", MNU_PARALLEL, 'L', TN, mCon }, { 1, "Para&llel / Tangent", Command::PARALLEL, 'L', TN, mCon },
{ 1, "&Perpendicular", MNU_PERPENDICULAR, '[', TN, mCon }, { 1, "&Perpendicular", Command::PERPENDICULAR, '[', TN, mCon },
{ 1, "Same Orient&ation", MNU_ORIENTED_SAME, 'X', TN, mCon }, { 1, "Same Orient&ation", Command::ORIENTED_SAME, 'X', TN, mCon },
{ 1, "Lock Point Where &Dragged", MNU_WHERE_DRAGGED, ']', TN, mCon }, { 1, "Lock Point Where &Dragged", Command::WHERE_DRAGGED, ']', TN, mCon },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Comment", MNU_COMMENT, ';', TN, mCon }, { 1, "Comment", Command::COMMENT, ';', TN, mCon },
{ 0, "&Analyze", 0, 0, TN, NULL }, { 0, "&Analyze", Command::NONE, 0, TN, NULL },
{ 1, "Measure &Volume", MNU_VOLUME, C|S|'V', TN, mAna }, { 1, "Measure &Volume", Command::VOLUME, C|S|'V', TN, mAna },
{ 1, "Measure &Area", MNU_AREA, C|S|'A', TN, mAna }, { 1, "Measure &Area", Command::AREA, C|S|'A', TN, mAna },
{ 1, "Show &Interfering Parts", MNU_INTERFERENCE, C|S|'I', TN, mAna }, { 1, "Show &Interfering Parts", Command::INTERFERENCE, C|S|'I', TN, mAna },
{ 1, "Show &Naked Edges", MNU_NAKED_EDGES, C|S|'N', TN, mAna }, { 1, "Show &Naked Edges", Command::NAKED_EDGES, C|S|'N', TN, mAna },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Show Degrees of &Freedom", MNU_SHOW_DOF, C|S|'F', TN, mAna }, { 1, "Show Degrees of &Freedom", Command::SHOW_DOF, C|S|'F', TN, mAna },
{ 1, NULL, 0, 0, TN, NULL }, { 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Trace Point", MNU_TRACE_PT, C|S|'T', TN, mAna }, { 1, "&Trace Point", Command::TRACE_PT, C|S|'T', TN, mAna },
{ 1, "&Stop Tracing...", MNU_STOP_TRACING, C|S|'S', TN, mAna }, { 1, "&Stop Tracing...", Command::STOP_TRACING, C|S|'S', TN, mAna },
{ 1, "Step &Dimension...", MNU_STEP_DIM, C|S|'D', TN, mAna }, { 1, "Step &Dimension...", Command::STEP_DIM, C|S|'D', TN, mAna },
{ 0, "&Help", 0, 0, TN, NULL }, { 0, "&Help", Command::NONE, 0, TN, NULL },
{ 1, "&Website / Manual", MNU_WEBSITE, 0, TN, mHelp }, { 1, "&Website / Manual", Command::WEBSITE, 0, TN, mHelp },
#ifndef __APPLE__ #ifndef __APPLE__
{ 1, "&About", MNU_ABOUT, 0, TN, mHelp }, { 1, "&About", Command::ABOUT, 0, TN, mHelp },
#endif #endif
{ -1, 0, Command::NONE, 0, TN, 0 }
{ -1, 0, 0, 0, TN, 0 }
}; };
#undef DEL #undef DEL
@ -321,7 +320,7 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
for(Entity *e : entities) { for(Entity *e : entities) {
if(e->IsPoint()) { if(e->IsPoint()) {
HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, usePerspective); HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, usePerspective);
} else if(e->type == Entity::CIRCLE) { } else if(e->type == Entity::Type::CIRCLE) {
// Lots of entities can extend outside the bbox of their points, // Lots of entities can extend outside the bbox of their points,
// but circles are particularly bad. We want to get things halfway // but circles are particularly bad. We want to get things halfway
// reasonable without the mesh, because a zoom to fit is used to // reasonable without the mesh, because a zoom to fit is used to
@ -445,24 +444,24 @@ void GraphicsWindow::ZoomToFit(bool includingInvisibles, bool useSelection) {
} }
} }
void GraphicsWindow::MenuView(int id) { void GraphicsWindow::MenuView(Command id) {
switch(id) { switch(id) {
case MNU_ZOOM_IN: case Command::ZOOM_IN:
SS.GW.scale *= 1.2; SS.GW.scale *= 1.2;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
case MNU_ZOOM_OUT: case Command::ZOOM_OUT:
SS.GW.scale /= 1.2; SS.GW.scale /= 1.2;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
case MNU_ZOOM_TO_FIT: case Command::ZOOM_TO_FIT:
SS.GW.ZoomToFit(/*includingInvisibles=*/false, /*useSelection=*/true); SS.GW.ZoomToFit(/*includingInvisibles=*/false, /*useSelection=*/true);
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
case MNU_SHOW_GRID: case Command::SHOW_GRID:
SS.GW.showSnapGrid = !SS.GW.showSnapGrid; SS.GW.showSnapGrid = !SS.GW.showSnapGrid;
if(SS.GW.showSnapGrid && !SS.GW.LockedInWorkplane()) { if(SS.GW.showSnapGrid && !SS.GW.LockedInWorkplane()) {
Message("No workplane is active, so the grid will not " Message("No workplane is active, so the grid will not "
@ -472,7 +471,7 @@ void GraphicsWindow::MenuView(int id) {
InvalidateGraphics(); InvalidateGraphics();
break; break;
case MNU_PERSPECTIVE_PROJ: case Command::PERSPECTIVE_PROJ:
SS.usePerspectiveProj = !SS.usePerspectiveProj; SS.usePerspectiveProj = !SS.usePerspectiveProj;
if(SS.cameraTangent < 1e-6) { if(SS.cameraTangent < 1e-6) {
Error("The perspective factor is set to zero, so the view will " Error("The perspective factor is set to zero, so the view will "
@ -485,15 +484,15 @@ void GraphicsWindow::MenuView(int id) {
InvalidateGraphics(); InvalidateGraphics();
break; break;
case MNU_ONTO_WORKPLANE: case Command::ONTO_WORKPLANE:
if(SS.GW.LockedInWorkplane()) { if(SS.GW.LockedInWorkplane()) {
SS.GW.AnimateOntoWorkplane(); SS.GW.AnimateOntoWorkplane();
SS.GW.ClearSuper(); SS.GW.ClearSuper();
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
} // if not in 2d mode fall through and use ORTHO logic } // if not in 2d mode fall through and use ORTHO logic
case MNU_NEAREST_ORTHO: case Command::NEAREST_ORTHO:
case MNU_NEAREST_ISO: { case Command::NEAREST_ISO: {
static const Vector ortho[3] = { static const Vector ortho[3] = {
Vector::From(1, 0, 0), Vector::From(1, 0, 0),
Vector::From(0, 1, 0), Vector::From(0, 1, 0),
@ -517,7 +516,7 @@ void GraphicsWindow::MenuView(int id) {
Vector on = ou.Cross(ov); Vector on = ou.Cross(ov);
Vector u, v; Vector u, v;
if(id == MNU_NEAREST_ORTHO || id == MNU_ONTO_WORKPLANE) { if(id == Command::NEAREST_ORTHO || id == Command::ONTO_WORKPLANE) {
u = ou; u = ou;
v = ov; v = ov;
} else { } else {
@ -547,7 +546,7 @@ void GraphicsWindow::MenuView(int id) {
break; break;
} }
case MNU_CENTER_VIEW: case Command::CENTER_VIEW:
SS.GW.GroupSelection(); SS.GW.GroupSelection();
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) { if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
Quaternion quat0; Quaternion quat0;
@ -562,36 +561,36 @@ void GraphicsWindow::MenuView(int id) {
} }
break; break;
case MNU_SHOW_MENU_BAR: case Command::SHOW_MENU_BAR:
ToggleMenuBar(); ToggleMenuBar();
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
InvalidateGraphics(); InvalidateGraphics();
break; break;
case MNU_SHOW_TOOLBAR: case Command::SHOW_TOOLBAR:
SS.showToolbar = !SS.showToolbar; SS.showToolbar = !SS.showToolbar;
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
InvalidateGraphics(); InvalidateGraphics();
break; break;
case MNU_SHOW_TEXT_WND: case Command::SHOW_TEXT_WND:
SS.GW.showTextWindow = !SS.GW.showTextWindow; SS.GW.showTextWindow = !SS.GW.showTextWindow;
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
case MNU_UNITS_INCHES: case Command::UNITS_INCHES:
SS.viewUnits = SolveSpaceUI::UNIT_INCHES; SS.viewUnits = Unit::INCHES;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
case MNU_UNITS_MM: case Command::UNITS_MM:
SS.viewUnits = SolveSpaceUI::UNIT_MM; SS.viewUnits = Unit::MM;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
case MNU_FULL_SCREEN: case Command::FULL_SCREEN:
ToggleFullScreen(); ToggleFullScreen();
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
break; break;
@ -622,7 +621,7 @@ void GraphicsWindow::EnsureValidActives() {
activeGroup = SS.CreateDefaultDrawingGroup(); activeGroup = SS.CreateDefaultDrawingGroup();
// We've created the default group, but not the workplane entity; // We've created the default group, but not the workplane entity;
// do it now so that drawing mode isn't switched to "Free in 3d". // do it now so that drawing mode isn't switched to "Free in 3d".
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
} else { } else {
activeGroup = SK.groupOrder.elem[i]; activeGroup = SK.groupOrder.elem[i];
} }
@ -649,33 +648,33 @@ void GraphicsWindow::EnsureValidActives() {
// And update the checked state for various menus // And update the checked state for various menus
bool locked = LockedInWorkplane(); bool locked = LockedInWorkplane();
RadioMenuById(MNU_FREE_IN_3D, !locked); RadioMenuByCmd(Command::FREE_IN_3D, !locked);
RadioMenuById(MNU_SEL_WORKPLANE, locked); RadioMenuByCmd(Command::SEL_WORKPLANE, locked);
SS.UndoEnableMenus(); SS.UndoEnableMenus();
switch(SS.viewUnits) { switch(SS.viewUnits) {
case SolveSpaceUI::UNIT_MM: case Unit::MM:
case SolveSpaceUI::UNIT_INCHES: case Unit::INCHES:
break; break;
default: default:
SS.viewUnits = SolveSpaceUI::UNIT_MM; SS.viewUnits = Unit::MM;
break; break;
} }
RadioMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpaceUI::UNIT_MM); RadioMenuByCmd(Command::UNITS_MM, SS.viewUnits == Unit::MM);
RadioMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpaceUI::UNIT_INCHES); RadioMenuByCmd(Command::UNITS_INCHES, SS.viewUnits == Unit::INCHES);
ShowTextWindow(SS.GW.showTextWindow); ShowTextWindow(SS.GW.showTextWindow);
CheckMenuById(MNU_SHOW_TEXT_WND, SS.GW.showTextWindow); CheckMenuByCmd(Command::SHOW_TEXT_WND, SS.GW.showTextWindow);
#if defined(__APPLE__) #if defined(__APPLE__)
CheckMenuById(MNU_SHOW_MENU_BAR, MenuBarIsVisible()); CheckMenuByCmd(Command::SHOW_MENU_BAR, MenuBarIsVisible());
#endif #endif
CheckMenuById(MNU_SHOW_TOOLBAR, SS.showToolbar); CheckMenuByCmd(Command::SHOW_TOOLBAR, SS.showToolbar);
CheckMenuById(MNU_PERSPECTIVE_PROJ, SS.usePerspectiveProj); CheckMenuByCmd(Command::PERSPECTIVE_PROJ, SS.usePerspectiveProj);
CheckMenuById(MNU_SHOW_GRID, SS.GW.showSnapGrid); CheckMenuByCmd(Command::SHOW_GRID, SS.GW.showSnapGrid);
#if defined(HAVE_GTK) || defined(__APPLE__) #if defined(HAVE_GTK) || defined(__APPLE__)
CheckMenuById(MNU_FULL_SCREEN, FullScreenIsActive()); CheckMenuByCmd(Command::FULL_SCREEN, FullScreenIsActive());
#endif #endif
if(change) SS.ScheduleShowTW(); if(change) SS.ScheduleShowTW();
@ -699,7 +698,7 @@ bool GraphicsWindow::LockedInWorkplane() {
void GraphicsWindow::ForceTextWindowShown() { void GraphicsWindow::ForceTextWindowShown() {
if(!showTextWindow) { if(!showTextWindow) {
showTextWindow = true; showTextWindow = true;
CheckMenuById(MNU_SHOW_TEXT_WND, true); CheckMenuByCmd(Command::SHOW_TEXT_WND, true);
ShowTextWindow(true); ShowTextWindow(true);
} }
} }
@ -723,7 +722,7 @@ void GraphicsWindow::DeleteTaggedRequests() {
ClearSuper(); ClearSuper();
// And regenerate to get rid of what it generates, plus anything // And regenerate to get rid of what it generates, plus anything
// that references it (since the regen code checks for that). // that references it (since the regen code checks for that).
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
EnsureValidActives(); EnsureValidActives();
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
@ -746,9 +745,9 @@ Vector GraphicsWindow::SnapToGrid(Vector p) {
return pp.ScaleOutOfCsys(wu, wv, wn).Plus(wo); return pp.ScaleOutOfCsys(wu, wv, wn).Plus(wo);
} }
void GraphicsWindow::MenuEdit(int id) { void GraphicsWindow::MenuEdit(Command id) {
switch(id) { switch(id) {
case MNU_UNSELECT_ALL: case Command::UNSELECT_ALL:
SS.GW.GroupSelection(); SS.GW.GroupSelection();
// If there's nothing selected to de-select, and no operation // If there's nothing selected to de-select, and no operation
// to cancel, then perhaps they want to return to the home // to cancel, then perhaps they want to return to the home
@ -760,8 +759,8 @@ void GraphicsWindow::MenuEdit(int id) {
if(!(TextEditControlIsVisible() || if(!(TextEditControlIsVisible() ||
GraphicsEditControlIsVisible())) GraphicsEditControlIsVisible()))
{ {
if(SS.TW.shown.screen == TextWindow::SCREEN_STYLE_INFO) { if(SS.TW.shown.screen == TextWindow::Screen::STYLE_INFO) {
SS.TW.GoToScreen(TextWindow::SCREEN_LIST_OF_STYLES); SS.TW.GoToScreen(TextWindow::Screen::LIST_OF_STYLES);
} else { } else {
SS.TW.ClearSuper(); SS.TW.ClearSuper();
} }
@ -779,11 +778,11 @@ void GraphicsWindow::MenuEdit(int id) {
} }
if(SS.exportMode) { if(SS.exportMode) {
SS.exportMode = false; SS.exportMode = false;
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
} }
break; break;
case MNU_SELECT_ALL: { case Command::SELECT_ALL: {
Entity *e; Entity *e;
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
if(e->group.v != SS.GW.activeGroup.v) continue; if(e->group.v != SS.GW.activeGroup.v) continue;
@ -797,7 +796,7 @@ void GraphicsWindow::MenuEdit(int id) {
break; break;
} }
case MNU_SELECT_CHAIN: { case Command::SELECT_CHAIN: {
Entity *e; Entity *e;
int newlySelected = 0; int newlySelected = 0;
bool didSomething; bool didSomething;
@ -847,7 +846,7 @@ void GraphicsWindow::MenuEdit(int id) {
break; break;
} }
case MNU_ROTATE_90: { case Command::ROTATE_90: {
SS.GW.GroupSelection(); SS.GW.GroupSelection();
Entity *e = NULL; Entity *e = NULL;
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) { if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
@ -859,7 +858,7 @@ void GraphicsWindow::MenuEdit(int id) {
hGroup hg = e ? e->group : SS.GW.activeGroup; hGroup hg = e ? e->group : SS.GW.activeGroup;
Group *g = SK.GetGroup(hg); Group *g = SK.GetGroup(hg);
if(g->type != Group::LINKED) { if(g->type != Group::Type::LINKED) {
Error("To use this command, select a point or other " Error("To use this command, select a point or other "
"entity from an linked part, or make a link " "entity from an linked part, or make a link "
"group the active group."); "group the active group.");
@ -883,7 +882,7 @@ void GraphicsWindow::MenuEdit(int id) {
break; break;
} }
case MNU_SNAP_TO_GRID: { case Command::SNAP_TO_GRID: {
if(!SS.GW.LockedInWorkplane()) { if(!SS.GW.LockedInWorkplane()) {
Error("No workplane is active. Select a workplane to define " Error("No workplane is active. Select a workplane to define "
"the plane for the snap grid."); "the plane for the snap grid.");
@ -924,17 +923,17 @@ void GraphicsWindow::MenuEdit(int id) {
break; break;
} }
case MNU_UNDO: case Command::UNDO:
SS.UndoUndo(); SS.UndoUndo();
break; break;
case MNU_REDO: case Command::REDO:
SS.UndoRedo(); SS.UndoRedo();
break; break;
case MNU_REGEN_ALL: case Command::REGEN_ALL:
SS.ReloadAllImported(); SS.ReloadAllImported();
SS.GenerateAll(SolveSpaceUI::GENERATE_UNTIL_ACTIVE); SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE);
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
@ -942,17 +941,17 @@ void GraphicsWindow::MenuEdit(int id) {
} }
} }
void GraphicsWindow::MenuRequest(int id) { void GraphicsWindow::MenuRequest(Command id) {
const char *s; const char *s;
switch(id) { switch(id) {
case MNU_SEL_WORKPLANE: { case Command::SEL_WORKPLANE: {
SS.GW.GroupSelection(); SS.GW.GroupSelection();
Group *g = SK.GetGroup(SS.GW.activeGroup); Group *g = SK.GetGroup(SS.GW.activeGroup);
if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) { if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) {
// A user-selected workplane // A user-selected workplane
g->activeWorkplane = SS.GW.gs.entity[0]; g->activeWorkplane = SS.GW.gs.entity[0];
} else if(g->type == Group::DRAWING_WORKPLANE) { } else if(g->type == Group::Type::DRAWING_WORKPLANE) {
// The group's default workplane // The group's default workplane
g->activeWorkplane = g->h.entity(0); g->activeWorkplane = g->h.entity(0);
Message("No workplane selected. Activating default workplane " Message("No workplane selected. Activating default workplane "
@ -972,14 +971,14 @@ void GraphicsWindow::MenuRequest(int id) {
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
} }
case MNU_FREE_IN_3D: case Command::FREE_IN_3D:
SS.GW.SetWorkplaneFreeIn3d(); SS.GW.SetWorkplaneFreeIn3d();
SS.GW.EnsureValidActives(); SS.GW.EnsureValidActives();
SS.ScheduleShowTW(); SS.ScheduleShowTW();
InvalidateGraphics(); InvalidateGraphics();
break; break;
case MNU_TANGENT_ARC: case Command::TANGENT_ARC:
SS.GW.GroupSelection(); SS.GW.GroupSelection();
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) { if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
SS.GW.MakeTangentArc(); SS.GW.MakeTangentArc();
@ -988,30 +987,30 @@ void GraphicsWindow::MenuRequest(int id) {
"single point, or select nothing to set up arc " "single point, or select nothing to set up arc "
"parameters."); "parameters.");
} else { } else {
SS.TW.GoToScreen(TextWindow::SCREEN_TANGENT_ARC); SS.TW.GoToScreen(TextWindow::Screen::TANGENT_ARC);
SS.GW.ForceTextWindowShown(); SS.GW.ForceTextWindowShown();
SS.ScheduleShowTW(); SS.ScheduleShowTW();
InvalidateGraphics(); // repaint toolbar InvalidateGraphics(); // repaint toolbar
} }
break; break;
case MNU_ARC: s = "click point on arc (draws anti-clockwise)"; goto c; case Command::ARC: s = "click point on arc (draws anti-clockwise)"; goto c;
case MNU_DATUM_POINT: s = "click to place datum point"; goto c; case Command::DATUM_POINT: s = "click to place datum point"; goto c;
case MNU_LINE_SEGMENT: s = "click first point of line segment"; goto c; case Command::LINE_SEGMENT: s = "click first point of line segment"; goto c;
case MNU_CONSTR_SEGMENT: s = "click first point of construction line segment"; goto c; case Command::CONSTR_SEGMENT: s = "click first point of construction line segment"; goto c;
case MNU_CUBIC: s = "click first point of cubic segment"; goto c; case Command::CUBIC: s = "click first point of cubic segment"; goto c;
case MNU_CIRCLE: s = "click center of circle"; goto c; case Command::CIRCLE: s = "click center of circle"; goto c;
case MNU_WORKPLANE: s = "click origin of workplane"; goto c; case Command::WORKPLANE: s = "click origin of workplane"; goto c;
case MNU_RECTANGLE: s = "click one corner of rectangle"; goto c; case Command::RECTANGLE: s = "click one corner of rectangle"; goto c;
case MNU_TTF_TEXT: s = "click top left of text"; goto c; case Command::TTF_TEXT: s = "click top left of text"; goto c;
c: c:
SS.GW.pending.operation = id; SS.GW.pending.operation = (uint32_t)id;
SS.GW.pending.description = s; SS.GW.pending.description = s;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
InvalidateGraphics(); // repaint toolbar InvalidateGraphics(); // repaint toolbar
break; break;
case MNU_CONSTRUCTION: { case Command::CONSTRUCTION: {
SS.UndoRemember(); SS.UndoRemember();
SS.GW.GroupSelection(); SS.GW.GroupSelection();
if(SS.GW.gs.entities == 0) { if(SS.GW.gs.entities == 0) {
@ -1031,7 +1030,7 @@ c:
break; break;
} }
case MNU_SPLIT_CURVES: case Command::SPLIT_CURVES:
SS.GW.SplitLinesOrCurves(); SS.GW.SplitLinesOrCurves();
break; break;
@ -1063,7 +1062,7 @@ void GraphicsWindow::ToggleBool(bool *v) {
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
GraphicsWindow::SuggestedConstraint GraphicsWindow::SuggestLineConstraint(hRequest request) { Constraint::Type GraphicsWindow::SuggestLineConstraint(hRequest request) {
if(LockedInWorkplane()) { if(LockedInWorkplane()) {
Entity *ptA = SK.GetEntity(request.entity(1)), Entity *ptA = SK.GetEntity(request.entity(1)),
*ptB = SK.GetEntity(request.entity(2)); *ptB = SK.GetEntity(request.entity(2));
@ -1078,12 +1077,12 @@ GraphicsWindow::SuggestedConstraint GraphicsWindow::SuggestLineConstraint(hReque
const double TOLERANCE_RATIO = 0.02; const double TOLERANCE_RATIO = 0.02;
if(fabs(dv) > LENGTH_EPS && fabs(du / dv) < TOLERANCE_RATIO) if(fabs(dv) > LENGTH_EPS && fabs(du / dv) < TOLERANCE_RATIO)
return SUGGESTED_VERTICAL; return Constraint::Type::VERTICAL;
else if(fabs(du) > LENGTH_EPS && fabs(dv / du) < TOLERANCE_RATIO) else if(fabs(du) > LENGTH_EPS && fabs(dv / du) < TOLERANCE_RATIO)
return SUGGESTED_HORIZONTAL; return Constraint::Type::HORIZONTAL;
else else
return SUGGESTED_NONE; return Constraint::Type::UNKNOWN;
} else { } else {
return SUGGESTED_NONE; return Constraint::Type::UNKNOWN;
} }
} }

View File

@ -71,30 +71,31 @@ void Group::ExtrusionForceVectorTo(const Vector &v) {
SK.GetParam(h.param(2))->val = v.z; SK.GetParam(h.param(2))->val = v.z;
} }
void Group::MenuGroup(int id) { void Group::MenuGroup(Command id) {
Group g = {}; Group g = {};
g.visible = true; g.visible = true;
g.color = RGBi(100, 100, 100); g.color = RGBi(100, 100, 100);
g.scale = 1; g.scale = 1;
if(id >= RECENT_LINK && id < (RECENT_LINK + MAX_RECENT)) { if((uint32_t)id >= (uint32_t)Command::RECENT_LINK &&
g.linkFile = RecentFile[id-RECENT_LINK]; (uint32_t)id < ((uint32_t)Command::RECENT_LINK + MAX_RECENT)) {
id = GraphicsWindow::MNU_GROUP_LINK; g.linkFile = RecentFile[(uint32_t)id-(uint32_t)Command::RECENT_LINK];
id = Command::GROUP_LINK;
} }
SS.GW.GroupSelection(); SS.GW.GroupSelection();
switch(id) { switch(id) {
case GraphicsWindow::MNU_GROUP_3D: case Command::GROUP_3D:
g.type = DRAWING_3D; g.type = Type::DRAWING_3D;
g.name = "sketch-in-3d"; g.name = "sketch-in-3d";
break; break;
case GraphicsWindow::MNU_GROUP_WRKPL: case Command::GROUP_WRKPL:
g.type = DRAWING_WORKPLANE; g.type = Type::DRAWING_WORKPLANE;
g.name = "sketch-in-plane"; g.name = "sketch-in-plane";
if(gs.points == 1 && gs.n == 1) { if(gs.points == 1 && gs.n == 1) {
g.subtype = WORKPLANE_BY_POINT_ORTHO; g.subtype = Subtype::WORKPLANE_BY_POINT_ORTHO;
Vector u = SS.GW.projRight, v = SS.GW.projUp; Vector u = SS.GW.projRight, v = SS.GW.projUp;
u = u.ClosestOrtho(); u = u.ClosestOrtho();
@ -104,7 +105,7 @@ void Group::MenuGroup(int id) {
g.predef.q = Quaternion::From(u, v); g.predef.q = Quaternion::From(u, v);
g.predef.origin = gs.point[0]; g.predef.origin = gs.point[0];
} else if(gs.points == 1 && gs.lineSegments == 2 && gs.n == 3) { } else if(gs.points == 1 && gs.lineSegments == 2 && gs.n == 3) {
g.subtype = WORKPLANE_BY_LINE_SEGMENTS; g.subtype = Subtype::WORKPLANE_BY_LINE_SEGMENTS;
g.predef.origin = gs.point[0]; g.predef.origin = gs.point[0];
g.predef.entityB = gs.entity[0]; g.predef.entityB = gs.entity[0];
@ -132,21 +133,21 @@ void Group::MenuGroup(int id) {
} }
break; break;
case GraphicsWindow::MNU_GROUP_EXTRUDE: case Command::GROUP_EXTRUDE:
if(!SS.GW.LockedInWorkplane()) { if(!SS.GW.LockedInWorkplane()) {
Error("Select a workplane (Sketch -> In Workplane) before " Error("Select a workplane (Sketch -> In Workplane) before "
"extruding. The sketch will be extruded normal to the " "extruding. The sketch will be extruded normal to the "
"workplane."); "workplane.");
return; return;
} }
g.type = EXTRUDE; g.type = Type::EXTRUDE;
g.opA = SS.GW.activeGroup; g.opA = SS.GW.activeGroup;
g.predef.entityB = SS.GW.ActiveWorkplane(); g.predef.entityB = SS.GW.ActiveWorkplane();
g.subtype = ONE_SIDED; g.subtype = Subtype::ONE_SIDED;
g.name = "extrude"; g.name = "extrude";
break; break;
case GraphicsWindow::MNU_GROUP_LATHE: case Command::GROUP_LATHE:
if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) { if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) {
g.predef.origin = gs.point[0]; g.predef.origin = gs.point[0];
g.predef.entityB = gs.vector[0]; g.predef.entityB = gs.vector[0];
@ -163,12 +164,12 @@ void Group::MenuGroup(int id) {
" * a line segment (revolved about line segment)\n"); " * a line segment (revolved about line segment)\n");
return; return;
} }
g.type = LATHE; g.type = Type::LATHE;
g.opA = SS.GW.activeGroup; g.opA = SS.GW.activeGroup;
g.name = "lathe"; g.name = "lathe";
break; break;
case GraphicsWindow::MNU_GROUP_ROT: { case Command::GROUP_ROT: {
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) { if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
g.predef.origin = gs.point[0]; g.predef.origin = gs.point[0];
Entity *w = SK.GetEntity(SS.GW.ActiveWorkplane()); Entity *w = SK.GetEntity(SS.GW.ActiveWorkplane());
@ -187,26 +188,26 @@ void Group::MenuGroup(int id) {
"line / normal)\n"); "line / normal)\n");
return; return;
} }
g.type = ROTATE; g.type = Type::ROTATE;
g.opA = SS.GW.activeGroup; g.opA = SS.GW.activeGroup;
g.valA = 3; g.valA = 3;
g.subtype = ONE_SIDED; g.subtype = Subtype::ONE_SIDED;
g.name = "rotate"; g.name = "rotate";
break; break;
} }
case GraphicsWindow::MNU_GROUP_TRANS: case Command::GROUP_TRANS:
g.type = TRANSLATE; g.type = Type::TRANSLATE;
g.opA = SS.GW.activeGroup; g.opA = SS.GW.activeGroup;
g.valA = 3; g.valA = 3;
g.subtype = ONE_SIDED; g.subtype = Subtype::ONE_SIDED;
g.predef.entityB = SS.GW.ActiveWorkplane(); g.predef.entityB = SS.GW.ActiveWorkplane();
g.activeWorkplane = SS.GW.ActiveWorkplane(); g.activeWorkplane = SS.GW.ActiveWorkplane();
g.name = "translate"; g.name = "translate";
break; break;
case GraphicsWindow::MNU_GROUP_LINK: { case Command::GROUP_LINK: {
g.type = LINKED; g.type = Type::LINKED;
if(g.linkFile.empty()) { if(g.linkFile.empty()) {
if(!GetOpenFile(&g.linkFile, "", SlvsFileFilter)) return; if(!GetOpenFile(&g.linkFile, "", SlvsFileFilter)) return;
} }
@ -237,7 +238,7 @@ void Group::MenuGroup(int id) {
g.name = "link"; g.name = "link";
} }
g.meshCombine = COMBINE_AS_ASSEMBLE; g.meshCombine = CombineAs::ASSEMBLE;
break; break;
} }
@ -269,13 +270,13 @@ void Group::MenuGroup(int id) {
SK.group.AddAndAssignId(&g); SK.group.AddAndAssignId(&g);
Group *gg = SK.GetGroup(g.h); Group *gg = SK.GetGroup(g.h);
if(gg->type == LINKED) { if(gg->type == Type::LINKED) {
SS.ReloadAllImported(); SS.ReloadAllImported();
} }
gg->clean = false; gg->clean = false;
SS.GW.activeGroup = gg->h; SS.GW.activeGroup = gg->h;
SS.GenerateAll(); SS.GenerateAll();
if(gg->type == DRAWING_WORKPLANE) { if(gg->type == Type::DRAWING_WORKPLANE) {
// Can't set the active workplane for this one until after we've // Can't set the active workplane for this one until after we've
// regenerated, because the workplane doesn't exist until then. // regenerated, because the workplane doesn't exist until then.
gg->activeWorkplane = gg->h.entity(0); gg->activeWorkplane = gg->h.entity(0);
@ -287,7 +288,7 @@ void Group::MenuGroup(int id) {
} }
void Group::TransformImportedBy(Vector t, Quaternion q) { void Group::TransformImportedBy(Vector t, Quaternion q) {
ssassert(type == LINKED, "Expected a linked group"); ssassert(type == Type::LINKED, "Expected a linked group");
hParam tx, ty, tz, qw, qx, qy, qz; hParam tx, ty, tz, qw, qx, qy, qz;
tx = h.param(0); tx = h.param(0);
@ -323,7 +324,8 @@ std::string Group::DescriptionString() {
} }
void Group::Activate() { void Group::Activate() {
if(type == EXTRUDE || type == LINKED || type == LATHE || type == TRANSLATE || type == ROTATE) { if(type == Type::EXTRUDE || type == Type::LINKED || type == Type::LATHE ||
type == Type::TRANSLATE || type == Type::ROTATE) {
SS.GW.showFaces = true; SS.GW.showFaces = true;
} else { } else {
SS.GW.showFaces = false; SS.GW.showFaces = false;
@ -343,12 +345,12 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
gp = gp.WithMagnitude(200/SS.GW.scale); gp = gp.WithMagnitude(200/SS.GW.scale);
int a, i; int a, i;
switch(type) { switch(type) {
case DRAWING_3D: case Type::DRAWING_3D:
break; break;
case DRAWING_WORKPLANE: { case Type::DRAWING_WORKPLANE: {
Quaternion q; Quaternion q;
if(subtype == WORKPLANE_BY_LINE_SEGMENTS) { if(subtype == Subtype::WORKPLANE_BY_LINE_SEGMENTS) {
Vector u = SK.GetEntity(predef.entityB)->VectorGetNum(); Vector u = SK.GetEntity(predef.entityB)->VectorGetNum();
Vector v = SK.GetEntity(predef.entityC)->VectorGetNum(); Vector v = SK.GetEntity(predef.entityC)->VectorGetNum();
u = u.WithMagnitude(1); u = u.WithMagnitude(1);
@ -359,13 +361,13 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
if(predef.negateU) u = u.ScaledBy(-1); if(predef.negateU) u = u.ScaledBy(-1);
if(predef.negateV) v = v.ScaledBy(-1); if(predef.negateV) v = v.ScaledBy(-1);
q = Quaternion::From(u, v); q = Quaternion::From(u, v);
} else if(subtype == WORKPLANE_BY_POINT_ORTHO) { } else if(subtype == Subtype::WORKPLANE_BY_POINT_ORTHO) {
// Already given, numerically. // Already given, numerically.
q = predef.q; q = predef.q;
} else ssassert(false, "Unexpected workplane subtype"); } else ssassert(false, "Unexpected workplane subtype");
Entity normal = {}; Entity normal = {};
normal.type = Entity::NORMAL_N_COPY; normal.type = Entity::Type::NORMAL_N_COPY;
normal.numNormal = q; normal.numNormal = q;
normal.point[0] = h.entity(2); normal.point[0] = h.entity(2);
normal.group = h; normal.group = h;
@ -373,14 +375,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
entity->Add(&normal); entity->Add(&normal);
Entity point = {}; Entity point = {};
point.type = Entity::POINT_N_COPY; point.type = Entity::Type::POINT_N_COPY;
point.numPoint = SK.GetEntity(predef.origin)->PointGetNum(); point.numPoint = SK.GetEntity(predef.origin)->PointGetNum();
point.group = h; point.group = h;
point.h = h.entity(2); point.h = h.entity(2);
entity->Add(&point); entity->Add(&point);
Entity wp = {}; Entity wp = {};
wp.type = Entity::WORKPLANE; wp.type = Entity::Type::WORKPLANE;
wp.normal = normal.h; wp.normal = normal.h;
wp.point[0] = point.h; wp.point[0] = point.h;
wp.group = h; wp.group = h;
@ -389,14 +391,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
break; break;
} }
case EXTRUDE: { case Type::EXTRUDE: {
AddParam(param, h.param(0), gn.x); AddParam(param, h.param(0), gn.x);
AddParam(param, h.param(1), gn.y); AddParam(param, h.param(1), gn.y);
AddParam(param, h.param(2), gn.z); AddParam(param, h.param(2), gn.z);
int ai, af; int ai, af;
if(subtype == ONE_SIDED) { if(subtype == Subtype::ONE_SIDED) {
ai = 0; af = 2; ai = 0; af = 2;
} else if(subtype == TWO_SIDED) { } else if(subtype == Subtype::TWO_SIDED) {
ai = -1; af = 1; ai = -1; af = 1;
} else ssassert(false, "Unexpected extrusion subtype"); } else ssassert(false, "Unexpected extrusion subtype");
@ -429,7 +431,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
break; break;
} }
case LATHE: { case Type::LATHE: {
Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum(); Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum();
Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum(); Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum();
@ -470,14 +472,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
break; break;
} }
case TRANSLATE: { case Type::TRANSLATE: {
// The translation vector // The translation vector
AddParam(param, h.param(0), gp.x); AddParam(param, h.param(0), gp.x);
AddParam(param, h.param(1), gp.y); AddParam(param, h.param(1), gp.y);
AddParam(param, h.param(2), gp.z); AddParam(param, h.param(2), gp.z);
int n = (int)valA, a0 = 0; int n = (int)valA, a0 = 0;
if(subtype == ONE_SIDED && skipFirst) { if(subtype == Subtype::ONE_SIDED && skipFirst) {
a0++; n++; a0++; n++;
} }
@ -488,7 +490,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
e->CalculateNumerical(false); e->CalculateNumerical(false);
CopyEntity(entity, e, CopyEntity(entity, e,
a*2 - (subtype == ONE_SIDED ? 0 : (n-1)), a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)),
(a == (n - 1)) ? REMAP_LAST : a, (a == (n - 1)) ? REMAP_LAST : a,
h.param(0), h.param(1), h.param(2), h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
@ -497,7 +499,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
} }
break; break;
} }
case ROTATE: { case Type::ROTATE: {
// The center of rotation // The center of rotation
AddParam(param, h.param(0), gc.x); AddParam(param, h.param(0), gc.x);
AddParam(param, h.param(1), gc.y); AddParam(param, h.param(1), gc.y);
@ -509,7 +511,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
AddParam(param, h.param(6), gn.z); AddParam(param, h.param(6), gn.z);
int n = (int)valA, a0 = 0; int n = (int)valA, a0 = 0;
if(subtype == ONE_SIDED && skipFirst) { if(subtype == Subtype::ONE_SIDED && skipFirst) {
a0++; n++; a0++; n++;
} }
@ -520,7 +522,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
e->CalculateNumerical(false); e->CalculateNumerical(false);
CopyEntity(entity, e, CopyEntity(entity, e,
a*2 - (subtype == ONE_SIDED ? 0 : (n-1)), a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)),
(a == (n - 1)) ? REMAP_LAST : a, (a == (n - 1)) ? REMAP_LAST : a,
h.param(0), h.param(1), h.param(2), h.param(0), h.param(1), h.param(2),
h.param(3), h.param(4), h.param(5), h.param(6), h.param(3), h.param(4), h.param(5), h.param(6),
@ -529,7 +531,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
} }
break; break;
} }
case LINKED: case Type::LINKED:
// The translation vector // The translation vector
AddParam(param, h.param(0), gp.x); AddParam(param, h.param(0), gp.x);
AddParam(param, h.param(1), gp.y); AddParam(param, h.param(1), gp.y);
@ -554,8 +556,8 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
} }
bool Group::IsSolvedOkay() { bool Group::IsSolvedOkay() {
return this->solved.how == System::SOLVED_OKAY || return this->solved.how == SolveResult::OKAY ||
(this->allowRedundant && this->solved.how == System::REDUNDANT_OKAY); (this->allowRedundant && this->solved.how == SolveResult::REDUNDANT_OKAY);
} }
void Group::AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) { void Group::AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) {
@ -566,7 +568,7 @@ void Group::AddEq(IdList<Equation,hEquation> *l, Expr *expr, int index) {
} }
void Group::GenerateEquations(IdList<Equation,hEquation> *l) { void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
if(type == LINKED) { if(type == Type::LINKED) {
// Normalize the quaternion // Normalize the quaternion
ExprQuaternion q = { ExprQuaternion q = {
Expr::From(h.param(3)), Expr::From(h.param(3)),
@ -574,7 +576,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
Expr::From(h.param(5)), Expr::From(h.param(5)),
Expr::From(h.param(6)) }; Expr::From(h.param(6)) };
AddEq(l, (q.Magnitude())->Minus(Expr::From(1)), 0); AddEq(l, (q.Magnitude())->Minus(Expr::From(1)), 0);
} else if(type == ROTATE) { } else if(type == Type::ROTATE) {
// The axis and center of rotation are specified numerically // The axis and center of rotation are specified numerically
#define EC(x) (Expr::From(x)) #define EC(x) (Expr::From(x))
#define EP(x) (Expr::From(h.param(x))) #define EP(x) (Expr::From(h.param(x)))
@ -590,7 +592,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
AddEq(l, (EC(axis.z))->Minus(EP(6)), 5); AddEq(l, (EC(axis.z))->Minus(EP(6)), 5);
#undef EC #undef EC
#undef EP #undef EP
} else if(type == EXTRUDE) { } else if(type == Type::EXTRUDE) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) { if(predef.entityB.v != Entity::FREE_IN_3D.v) {
// The extrusion path is locked along a line, normal to the // The extrusion path is locked along a line, normal to the
// specified workplane. // specified workplane.
@ -605,7 +607,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
AddEq(l, u.Dot(extruden), 0); AddEq(l, u.Dot(extruden), 0);
AddEq(l, v.Dot(extruden), 1); AddEq(l, v.Dot(extruden), 1);
} }
} else if(type == TRANSLATE) { } else if(type == Type::TRANSLATE) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) { if(predef.entityB.v != Entity::FREE_IN_3D.v) {
Entity *w = SK.GetEntity(predef.entityB); Entity *w = SK.GetEntity(predef.entityB);
ExprVector n = w->Normal()->NormalExprsN(); ExprVector n = w->Normal()->NormalExprsN();
@ -657,9 +659,9 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
en.construction = ep->construction; en.construction = ep->construction;
en.style = ep->style; en.style = ep->style;
en.h = Remap(ep->h, REMAP_PT_TO_LINE); en.h = Remap(ep->h, REMAP_PT_TO_LINE);
en.type = Entity::LINE_SEGMENT; en.type = Entity::Type::LINE_SEGMENT;
el->Add(&en); el->Add(&en);
} else if(ep->type == Entity::LINE_SEGMENT) { } else if(ep->type == Entity::Type::LINE_SEGMENT) {
// A line gets extruded to form a plane face; an endpoint of the // A line gets extruded to form a plane face; an endpoint of the
// original line is a point in the plane, and the line is in the plane. // original line is a point in the plane, and the line is in the plane.
Vector a = SK.GetEntity(ep->point[0])->PointGetNum(); Vector a = SK.GetEntity(ep->point[0])->PointGetNum();
@ -676,7 +678,7 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
en.construction = ep->construction; en.construction = ep->construction;
en.style = ep->style; en.style = ep->style;
en.h = Remap(ep->h, REMAP_LINE_TO_FACE); en.h = Remap(ep->h, REMAP_LINE_TO_FACE);
en.type = Entity::FACE_XPROD; en.type = Entity::Type::FACE_XPROD;
el->Add(&en); el->Add(&en);
} }
} }
@ -704,7 +706,7 @@ void Group::MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *p
en.construction = ep->construction; en.construction = ep->construction;
en.style = ep->style; en.style = ep->style;
en.h = Remap(ep->h, REMAP_PT_TO_ARC); en.h = Remap(ep->h, REMAP_PT_TO_ARC);
en.type = Entity::ARC_OF_CIRCLE; en.type = Entity::Type::ARC_OF_CIRCLE;
// Generate a normal. // Generate a normal.
Entity n = {}; Entity n = {};
@ -712,7 +714,7 @@ void Group::MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *p
n.h = Remap(ep->h, REMAP_PT_TO_NORMAL); n.h = Remap(ep->h, REMAP_PT_TO_NORMAL);
n.group = en.group; n.group = en.group;
n.style = en.style; n.style = en.style;
n.type = Entity::NORMAL_N_COPY; n.type = Entity::Type::NORMAL_N_COPY;
// Create basis for the normal. // Create basis for the normal.
Vector nu = pp->numPoint.Minus(pc->numPoint).WithMagnitude(1.0); Vector nu = pp->numPoint.Minus(pc->numPoint).WithMagnitude(1.0);
@ -725,7 +727,7 @@ void Group::MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *p
el->Add(&n); el->Add(&n);
en.normal = n.h; en.normal = n.h;
el->Add(&en); el->Add(&en);
} else if(ep->type == Entity::LINE_SEGMENT) { } else if(ep->type == Entity::Type::LINE_SEGMENT) {
// An axis-perpendicular line gets revolved to form a face. // An axis-perpendicular line gets revolved to form a face.
Vector a = SK.GetEntity(ep->point[0])->PointGetNum(); Vector a = SK.GetEntity(ep->point[0])->PointGetNum();
Vector b = SK.GetEntity(ep->point[1])->PointGetNum(); Vector b = SK.GetEntity(ep->point[1])->PointGetNum();
@ -746,7 +748,7 @@ void Group::MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *p
en.construction = ep->construction; en.construction = ep->construction;
en.style = ep->style; en.style = ep->style;
en.h = Remap(ep->h, REMAP_LINE_TO_FACE); en.h = Remap(ep->h, REMAP_LINE_TO_FACE);
en.type = Entity::FACE_NORMAL_PT; en.type = Entity::Type::FACE_NORMAL_PT;
en.point[0] = ep->point[0]; en.point[0] = ep->point[0];
el->Add(&en); el->Add(&en);
} }
@ -760,7 +762,7 @@ void Group::MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt)
Vector n = src->polyLoops.normal; Vector n = src->polyLoops.normal;
Entity en = {}; Entity en = {};
en.type = Entity::FACE_NORMAL_PT; en.type = Entity::Type::FACE_NORMAL_PT;
en.group = h; en.group = h;
en.numNormal = Quaternion::From(0, n.x, n.y, n.z); en.numNormal = Quaternion::From(0, n.x, n.y, n.z);
@ -791,26 +793,26 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.font = ep->font; en.font = ep->font;
switch(ep->type) { switch(ep->type) {
case Entity::WORKPLANE: case Entity::Type::WORKPLANE:
// Don't copy these. // Don't copy these.
return; return;
case Entity::POINT_N_COPY: case Entity::Type::POINT_N_COPY:
case Entity::POINT_N_TRANS: case Entity::Type::POINT_N_TRANS:
case Entity::POINT_N_ROT_TRANS: case Entity::Type::POINT_N_ROT_TRANS:
case Entity::POINT_N_ROT_AA: case Entity::Type::POINT_N_ROT_AA:
case Entity::POINT_IN_3D: case Entity::Type::POINT_IN_3D:
case Entity::POINT_IN_2D: case Entity::Type::POINT_IN_2D:
if(asTrans) { if(asTrans) {
en.type = Entity::POINT_N_TRANS; en.type = Entity::Type::POINT_N_TRANS;
en.param[0] = dx; en.param[0] = dx;
en.param[1] = dy; en.param[1] = dy;
en.param[2] = dz; en.param[2] = dz;
} else { } else {
if(asAxisAngle) { if(asAxisAngle) {
en.type = Entity::POINT_N_ROT_AA; en.type = Entity::Type::POINT_N_ROT_AA;
} else { } else {
en.type = Entity::POINT_N_ROT_TRANS; en.type = Entity::Type::POINT_N_ROT_TRANS;
} }
en.param[0] = dx; en.param[0] = dx;
en.param[1] = dy; en.param[1] = dy;
@ -823,18 +825,18 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.numPoint = (ep->actPoint).ScaledBy(scale); en.numPoint = (ep->actPoint).ScaledBy(scale);
break; break;
case Entity::NORMAL_N_COPY: case Entity::Type::NORMAL_N_COPY:
case Entity::NORMAL_N_ROT: case Entity::Type::NORMAL_N_ROT:
case Entity::NORMAL_N_ROT_AA: case Entity::Type::NORMAL_N_ROT_AA:
case Entity::NORMAL_IN_3D: case Entity::Type::NORMAL_IN_3D:
case Entity::NORMAL_IN_2D: case Entity::Type::NORMAL_IN_2D:
if(asTrans) { if(asTrans) {
en.type = Entity::NORMAL_N_COPY; en.type = Entity::Type::NORMAL_N_COPY;
} else { } else {
if(asAxisAngle) { if(asAxisAngle) {
en.type = Entity::NORMAL_N_ROT_AA; en.type = Entity::Type::NORMAL_N_ROT_AA;
} else { } else {
en.type = Entity::NORMAL_N_ROT; en.type = Entity::Type::NORMAL_N_ROT;
} }
en.param[0] = qw; en.param[0] = qw;
en.param[1] = qvx; en.param[1] = qvx;
@ -847,27 +849,27 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.point[0] = Remap(ep->point[0], remap); en.point[0] = Remap(ep->point[0], remap);
break; break;
case Entity::DISTANCE_N_COPY: case Entity::Type::DISTANCE_N_COPY:
case Entity::DISTANCE: case Entity::Type::DISTANCE:
en.type = Entity::DISTANCE_N_COPY; en.type = Entity::Type::DISTANCE_N_COPY;
en.numDistance = ep->actDistance*fabs(scale); en.numDistance = ep->actDistance*fabs(scale);
break; break;
case Entity::FACE_NORMAL_PT: case Entity::Type::FACE_NORMAL_PT:
case Entity::FACE_XPROD: case Entity::Type::FACE_XPROD:
case Entity::FACE_N_ROT_TRANS: case Entity::Type::FACE_N_ROT_TRANS:
case Entity::FACE_N_TRANS: case Entity::Type::FACE_N_TRANS:
case Entity::FACE_N_ROT_AA: case Entity::Type::FACE_N_ROT_AA:
if(asTrans) { if(asTrans) {
en.type = Entity::FACE_N_TRANS; en.type = Entity::Type::FACE_N_TRANS;
en.param[0] = dx; en.param[0] = dx;
en.param[1] = dy; en.param[1] = dy;
en.param[2] = dz; en.param[2] = dz;
} else { } else {
if(asAxisAngle) { if(asAxisAngle) {
en.type = Entity::FACE_N_ROT_AA; en.type = Entity::Type::FACE_N_ROT_AA;
} else { } else {
en.type = Entity::FACE_N_ROT_TRANS; en.type = Entity::Type::FACE_N_ROT_TRANS;
} }
en.param[0] = dx; en.param[0] = dx;
en.param[1] = dy; en.param[1] = dy;

View File

@ -58,24 +58,24 @@ void Group::GenerateLoops() {
bezierLoops.Clear(); bezierLoops.Clear();
bezierOpens.Clear(); bezierOpens.Clear();
if(type == DRAWING_3D || type == DRAWING_WORKPLANE || if(type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE ||
type == ROTATE || type == TRANSLATE || type == LINKED) type == Type::ROTATE || type == Type::TRANSLATE || type == Type::LINKED)
{ {
bool allClosed = false, allCoplanar = false, allNonZeroLen = false; bool allClosed = false, allCoplanar = false, allNonZeroLen = false;
AssembleLoops(&allClosed, &allCoplanar, &allNonZeroLen); AssembleLoops(&allClosed, &allCoplanar, &allNonZeroLen);
if(!allNonZeroLen) { if(!allNonZeroLen) {
polyError.how = POLY_ZERO_LEN_EDGE; polyError.how = PolyError::ZERO_LEN_EDGE;
} else if(!allCoplanar) { } else if(!allCoplanar) {
polyError.how = POLY_NOT_COPLANAR; polyError.how = PolyError::NOT_COPLANAR;
} else if(!allClosed) { } else if(!allClosed) {
polyError.how = POLY_NOT_CLOSED; polyError.how = PolyError::NOT_CLOSED;
} else { } else {
polyError.how = POLY_GOOD; polyError.how = PolyError::GOOD;
// The self-intersecting check is kind of slow, so don't run it // The self-intersecting check is kind of slow, so don't run it
// unless requested. // unless requested.
if(SS.checkClosedContour) { if(SS.checkClosedContour) {
if(polyLoops.SelfIntersecting(&(polyError.errorPointAt))) { if(polyLoops.SelfIntersecting(&(polyError.errorPointAt))) {
polyError.how = POLY_SELF_INTERSECTING; polyError.how = PolyError::SELF_INTERSECTING;
} }
} }
} }
@ -112,16 +112,16 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
T *soFar = &workA, *scratch = &workB; T *soFar = &workA, *scratch = &workB;
int n = (int)valA, a0 = 0; int n = (int)valA, a0 = 0;
if(subtype == ONE_SIDED && skipFirst) { if(subtype == Subtype::ONE_SIDED && skipFirst) {
a0++; n++; a0++; n++;
} }
int a; int a;
for(a = a0; a < n; a++) { for(a = a0; a < n; a++) {
int ap = a*2 - (subtype == ONE_SIDED ? 0 : (n-1)); int ap = a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1));
int remap = (a == (n - 1)) ? REMAP_LAST : a; int remap = (a == (n - 1)) ? REMAP_LAST : a;
T transd = {}; T transd = {};
if(type == TRANSLATE) { if(type == Type::TRANSLATE) {
Vector trans = Vector::From(h.param(0), h.param(1), h.param(2)); Vector trans = Vector::From(h.param(0), h.param(1), h.param(2));
trans = trans.ScaledBy(ap); trans = trans.ScaledBy(ap);
transd.MakeFromTransformationOf(steps, transd.MakeFromTransformationOf(steps,
@ -157,7 +157,7 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
} }
template<class T> template<class T>
void Group::GenerateForBoolean(T *prevs, T *thiss, T *outs, int how) { void Group::GenerateForBoolean(T *prevs, T *thiss, T *outs, Group::CombineAs how) {
// If this group contributes no new mesh, then our running mesh is the // If this group contributes no new mesh, then our running mesh is the
// same as last time, no combining required. Likewise if we have a mesh // same as last time, no combining required. Likewise if we have a mesh
// but it's suppressed. // but it's suppressed.
@ -168,9 +168,9 @@ void Group::GenerateForBoolean(T *prevs, T *thiss, T *outs, int how) {
// So our group's shell appears in thisShell. Combine this with the // So our group's shell appears in thisShell. Combine this with the
// previous group's shell, using the requested operation. // previous group's shell, using the requested operation.
if(how == COMBINE_AS_UNION) { if(how == CombineAs::UNION) {
outs->MakeFromUnionOf(prevs, thiss); outs->MakeFromUnionOf(prevs, thiss);
} else if(how == COMBINE_AS_DIFFERENCE) { } else if(how == CombineAs::DIFFERENCE) {
outs->MakeFromDifferenceOf(prevs, thiss); outs->MakeFromDifferenceOf(prevs, thiss);
} else { } else {
outs->MakeFromAssemblyOf(prevs, thiss); outs->MakeFromAssemblyOf(prevs, thiss);
@ -191,26 +191,26 @@ void Group::GenerateShellAndMesh() {
// Don't attempt a lathe or extrusion unless the source section is good: // Don't attempt a lathe or extrusion unless the source section is good:
// planar and not self-intersecting. // planar and not self-intersecting.
bool haveSrc = true; bool haveSrc = true;
if(type == EXTRUDE || type == LATHE) { if(type == Type::EXTRUDE || type == Type::LATHE) {
Group *src = SK.GetGroup(opA); Group *src = SK.GetGroup(opA);
if(src->polyError.how != POLY_GOOD) { if(src->polyError.how != PolyError::GOOD) {
haveSrc = false; haveSrc = false;
} }
} }
if(type == TRANSLATE || type == ROTATE) { if(type == Type::TRANSLATE || type == Type::ROTATE) {
// A step and repeat gets merged against the group's prevous group, // A step and repeat gets merged against the group's prevous group,
// not our own previous group. // not our own previous group.
srcg = SK.GetGroup(opA); srcg = SK.GetGroup(opA);
GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell); GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell);
GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh); GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh);
} else if(type == EXTRUDE && haveSrc) { } else if(type == Type::EXTRUDE && haveSrc) {
Group *src = SK.GetGroup(opA); Group *src = SK.GetGroup(opA);
Vector translate = Vector::From(h.param(0), h.param(1), h.param(2)); Vector translate = Vector::From(h.param(0), h.param(1), h.param(2));
Vector tbot, ttop; Vector tbot, ttop;
if(subtype == ONE_SIDED) { if(subtype == Subtype::ONE_SIDED) {
tbot = Vector::From(0, 0, 0); ttop = translate.ScaledBy(2); tbot = Vector::From(0, 0, 0); ttop = translate.ScaledBy(2);
} else { } else {
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1); tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
@ -254,7 +254,7 @@ void Group::GenerateShellAndMesh() {
Entity *e; Entity *e;
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
if(e->group.v != opA.v) continue; if(e->group.v != opA.v) continue;
if(e->type != Entity::LINE_SEGMENT) continue; if(e->type != Entity::Type::LINE_SEGMENT) continue;
Vector a = SK.GetEntity(e->point[0])->PointGetNum(), Vector a = SK.GetEntity(e->point[0])->PointGetNum(),
b = SK.GetEntity(e->point[1])->PointGetNum(); b = SK.GetEntity(e->point[1])->PointGetNum();
@ -273,7 +273,7 @@ void Group::GenerateShellAndMesh() {
} }
} }
} }
} else if(type == LATHE && haveSrc) { } else if(type == Type::LATHE && haveSrc) {
Group *src = SK.GetGroup(opA); Group *src = SK.GetGroup(opA);
Vector pt = SK.GetEntity(predef.origin)->PointGetNum(), Vector pt = SK.GetEntity(predef.origin)->PointGetNum(),
@ -285,7 +285,7 @@ void Group::GenerateShellAndMesh() {
for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) {
thisShell.MakeFromRevolutionOf(sbls, pt, axis, color, this); thisShell.MakeFromRevolutionOf(sbls, pt, axis, color, this);
} }
} else if(type == LINKED) { } else if(type == Type::LINKED) {
// The imported shell or mesh are copied over, with the appropriate // The imported shell or mesh are copied over, with the appropriate
// transformation applied. We also must remap the face entities. // transformation applied. We also must remap the face entities.
Vector offset = { Vector offset = {
@ -305,7 +305,7 @@ void Group::GenerateShellAndMesh() {
thisShell.RemapFaces(this, 0); thisShell.RemapFaces(this, 0);
} }
if(srcg->meshCombine != COMBINE_AS_ASSEMBLE) { if(srcg->meshCombine != CombineAs::ASSEMBLE) {
thisShell.MergeCoincidentSurfaces(); thisShell.MergeCoincidentSurfaces();
} }
@ -320,7 +320,7 @@ void Group::GenerateShellAndMesh() {
GenerateForBoolean<SShell>(prevs, &thisShell, &runningShell, GenerateForBoolean<SShell>(prevs, &thisShell, &runningShell,
srcg->meshCombine); srcg->meshCombine);
if(srcg->meshCombine != COMBINE_AS_ASSEMBLE) { if(srcg->meshCombine != CombineAs::ASSEMBLE) {
runningShell.MergeCoincidentSurfaces(); runningShell.MergeCoincidentSurfaces();
} }
@ -409,10 +409,10 @@ void Group::GenerateDisplayItems() {
if(runningMesh.l.n > 0) { if(runningMesh.l.n > 0) {
// Triangle mesh only; no shell or emphasized edges. // Triangle mesh only; no shell or emphasized edges.
runningMesh.MakeCertainEdgesAndOutlinesInto( runningMesh.MakeCertainEdgesAndOutlinesInto(
&displayEdges, &displayOutlines, SKdNode::EMPHASIZED_EDGES); &displayEdges, &displayOutlines, EdgeKind::EMPHASIZED);
} else { } else {
displayMesh.MakeCertainEdgesAndOutlinesInto( displayMesh.MakeCertainEdgesAndOutlinesInto(
&displayEdges, &displayOutlines, SKdNode::SHARP_EDGES); &displayEdges, &displayOutlines, EdgeKind::SHARP);
} }
} }
} }
@ -432,7 +432,7 @@ Group *Group::PreviousGroup() {
} }
Group *Group::RunningMeshGroup() { Group *Group::RunningMeshGroup() {
if(type == TRANSLATE || type == ROTATE) { if(type == Type::TRANSLATE || type == Type::ROTATE) {
return SK.GetGroup(opA)->RunningMeshGroup(); return SK.GetGroup(opA)->RunningMeshGroup();
} else { } else {
return PreviousGroup(); return PreviousGroup();
@ -441,19 +441,19 @@ Group *Group::RunningMeshGroup() {
bool Group::IsMeshGroup() { bool Group::IsMeshGroup() {
switch(type) { switch(type) {
case Group::EXTRUDE: case Group::Type::EXTRUDE:
case Group::LATHE: case Group::Type::LATHE:
case Group::ROTATE: case Group::Type::ROTATE:
case Group::TRANSLATE: case Group::Type::TRANSLATE:
return true; return true;
} }
return false; return false;
} }
void Group::DrawDisplayItems(int t) { void Group::DrawDisplayItems(Group::Type t) {
RgbaColor specColor; RgbaColor specColor;
bool useSpecColor; bool useSpecColor;
if(t == DRAWING_3D || t == DRAWING_WORKPLANE) { if(t == Type::DRAWING_3D || t == Type::DRAWING_WORKPLANE) {
// force the color to something dim // force the color to something dim
specColor = Style::Color(Style::DIM_SOLID); specColor = Style::Color(Style::DIM_SOLID);
useSpecColor = true; useSpecColor = true;
@ -530,10 +530,10 @@ void Group::Draw() {
// And finally show the polygons too, and any errors if it's not possible // And finally show the polygons too, and any errors if it's not possible
// to assemble the lines into closed polygons. // to assemble the lines into closed polygons.
if(polyError.how == POLY_NOT_CLOSED) { if(polyError.how == PolyError::NOT_CLOSED) {
// Report this error only in sketch-in-workplane groups; otherwise // Report this error only in sketch-in-workplane groups; otherwise
// it's just a nuisance. // it's just a nuisance.
if(type == DRAWING_WORKPLANE) { if(type == Type::DRAWING_WORKPLANE) {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
ssglColorRGBa(Style::Color(Style::DRAW_ERROR), 0.2); ssglColorRGBa(Style::Color(Style::DRAW_ERROR), 0.2);
ssglLineWidth (Style::Width(Style::DRAW_ERROR)); ssglLineWidth (Style::Width(Style::DRAW_ERROR));
@ -548,18 +548,18 @@ void Group::Draw() {
NULL, NULL); NULL, NULL);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
} else if(polyError.how == POLY_NOT_COPLANAR || } else if(polyError.how == PolyError::NOT_COPLANAR ||
polyError.how == POLY_SELF_INTERSECTING || polyError.how == PolyError::SELF_INTERSECTING ||
polyError.how == POLY_ZERO_LEN_EDGE) polyError.how == PolyError::ZERO_LEN_EDGE)
{ {
// These errors occur at points, not lines // These errors occur at points, not lines
if(type == DRAWING_WORKPLANE) { if(type == Type::DRAWING_WORKPLANE) {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
ssglColorRGB(Style::Color(Style::DRAW_ERROR)); ssglColorRGB(Style::Color(Style::DRAW_ERROR));
const char *msg; const char *msg;
if(polyError.how == POLY_NOT_COPLANAR) { if(polyError.how == PolyError::NOT_COPLANAR) {
msg = "points not all coplanar!"; msg = "points not all coplanar!";
} else if(polyError.how == POLY_SELF_INTERSECTING) { } else if(polyError.how == PolyError::SELF_INTERSECTING) {
msg = "contour is self-intersecting!"; msg = "contour is self-intersecting!";
} else { } else {
msg = "zero-length edge!"; msg = "zero-length edge!";
@ -599,7 +599,7 @@ void Group::DrawFilledPaths() {
FillLoopSetAsPolygon(sbls); FillLoopSetAsPolygon(sbls);
} else { } else {
if(h.v == SS.GW.activeGroup.v && SS.checkClosedContour && if(h.v == SS.GW.activeGroup.v && SS.checkClosedContour &&
polyError.how == POLY_GOOD) polyError.how == PolyError::GOOD)
{ {
// If this is the active group, and we are supposed to check // If this is the active group, and we are supposed to check
// for closed contours, and we do indeed have a closed and // for closed contours, and we do indeed have a closed and

View File

@ -124,7 +124,7 @@ public:
if(reversed) std::swap(p0, p1); if(reversed) std::swap(p0, p1);
blockTransformArc(&center, &p0, &p1); blockTransformArc(&center, &p0, &p1);
hRequest hr = SS.GW.AddRequest(Request::ARC_OF_CIRCLE, false); hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, false);
SK.GetEntity(hr.entity(1))->PointForceTo(center); SK.GetEntity(hr.entity(1))->PointForceTo(center);
SK.GetEntity(hr.entity(2))->PointForceTo(p0); SK.GetEntity(hr.entity(2))->PointForceTo(p0);
SK.GetEntity(hr.entity(3))->PointForceTo(p1); SK.GetEntity(hr.entity(3))->PointForceTo(p1);
@ -205,11 +205,11 @@ public:
} }
} }
int dxfAlignToOrigin(DRW_Text::HAlign alignH, DRW_Text::VAlign alignV) { Style::TextOrigin dxfAlignToOrigin(DRW_Text::HAlign alignH, DRW_Text::VAlign alignV) {
int origin = 0; uint32_t origin = 0;
switch(alignH) { switch(alignH) {
case DRW_Text::HLeft: case DRW_Text::HLeft:
origin |= Style::ORIGIN_LEFT; origin |= (uint32_t)Style::TextOrigin::LEFT;
break; break;
case DRW_Text::HMiddle: case DRW_Text::HMiddle:
@ -217,35 +217,35 @@ public:
break; break;
case DRW_Text::HRight: case DRW_Text::HRight:
origin |= Style::ORIGIN_RIGHT; origin |= (uint32_t)Style::TextOrigin::RIGHT;
break; break;
case DRW_Text::HAligned: case DRW_Text::HAligned:
case DRW_Text::HFit: case DRW_Text::HFit:
default: default:
origin |= Style::ORIGIN_LEFT; origin |= (uint32_t)Style::TextOrigin::LEFT;
break; break;
} }
switch(alignV) { switch(alignV) {
case DRW_Text::VBaseLine: case DRW_Text::VBaseLine:
case DRW_Text::VBottom: case DRW_Text::VBottom:
origin |= Style::ORIGIN_BOT; origin |= (uint32_t)Style::TextOrigin::BOT;
break; break;
case DRW_Text::VMiddle: case DRW_Text::VMiddle:
break; break;
case DRW_Text::VTop: case DRW_Text::VTop:
origin |= Style::ORIGIN_TOP; origin |= (uint32_t)Style::TextOrigin::TOP;
break; break;
default: default:
origin |= Style::ORIGIN_BOT; origin |= (uint32_t)Style::TextOrigin::BOT;
break; break;
} }
return origin; return (Style::TextOrigin)origin;
} }
DRW_Layer *getSourceLayer(const DRW_Entity *e) { DRW_Layer *getSourceLayer(const DRW_Entity *e) {
@ -355,10 +355,11 @@ public:
// Line stipple. // Line stipple.
// TODO: Probably, we can load default autocad patterns and match it with ours. // TODO: Probably, we can load default autocad patterns and match it with ours.
std::string lineType = getLineType(e); std::string lineType = getLineType(e);
int stipple = Style::STIPPLE_CONTINUOUS; StipplePattern stipple = StipplePattern::CONTINUOUS;
for(int i = 0; i <= Style::LAST_STIPPLE; i++) { for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) {
if(lineType == DxfFileWriter::lineTypeName(i)) { StipplePattern st = (StipplePattern)i;
stipple = i; if(lineType == DxfFileWriter::lineTypeName(st)) {
stipple = st;
break; break;
} }
} }
@ -406,14 +407,14 @@ public:
hStyle hs = { Style::CreateCustomStyle(/*rememberForUndo=*/false) }; hStyle hs = { Style::CreateCustomStyle(/*rememberForUndo=*/false) };
Style *s = Style::Get(hs); Style *s = Style::Get(hs);
if(lw != DRW_LW_Conv::widthDefault) { if(lw != DRW_LW_Conv::widthDefault) {
s->widthAs = Style::UNITS_AS_MM; s->widthAs = Style::UnitsAs::MM;
s->width = width; s->width = width;
s->stippleScale = 1.0 + width * 2.0; s->stippleScale = 1.0 + width * 2.0;
} }
s->name = id; s->name = id;
s->stippleType = stipple; s->stippleType = stipple;
if(c.red != 0 || c.green != 0 || c.blue != 0) s->color = c; if(c.red != 0 || c.green != 0 || c.blue != 0) s->color = c;
s->textHeightAs = Style::UNITS_AS_MM; s->textHeightAs = Style::UnitsAs::MM;
s->textHeight = textHeight; s->textHeight = textHeight;
s->textAngle = textAngle; s->textAngle = textAngle;
s->textOrigin = dxfAlignToOrigin(alignH, alignV); s->textOrigin = dxfAlignToOrigin(alignH, alignV);
@ -476,7 +477,7 @@ public:
hEntity he = findPoint(p); hEntity he = findPoint(p);
if(he.v != Entity::NO_ENTITY.v) return he; if(he.v != Entity::NO_ENTITY.v) return he;
hRequest hr = SS.GW.AddRequest(Request::DATUM_POINT, false); hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, false);
he = hr.entity(0); he = hr.entity(0);
SK.GetEntity(he)->PointForceTo(p); SK.GetEntity(he)->PointForceTo(p);
points.emplace(p, he); points.emplace(p, he);
@ -485,21 +486,21 @@ public:
hEntity createLine(Vector p0, Vector p1, uint32_t style, bool constrainHV = false) { hEntity createLine(Vector p0, Vector p1, uint32_t style, bool constrainHV = false) {
if(p0.Equals(p1)) return Entity::NO_ENTITY; if(p0.Equals(p1)) return Entity::NO_ENTITY;
hRequest hr = SS.GW.AddRequest(Request::LINE_SEGMENT, false); hRequest hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, false);
SK.GetEntity(hr.entity(1))->PointForceTo(p0); SK.GetEntity(hr.entity(1))->PointForceTo(p0);
SK.GetEntity(hr.entity(2))->PointForceTo(p1); SK.GetEntity(hr.entity(2))->PointForceTo(p1);
processPoint(hr.entity(1)); processPoint(hr.entity(1));
processPoint(hr.entity(2)); processPoint(hr.entity(2));
if(constrainHV) { if(constrainHV) {
int cType = -1; Constraint::Type cType = Constraint::Type::UNKNOWN;
if(fabs(p0.x - p1.x) < LENGTH_EPS) { if(fabs(p0.x - p1.x) < LENGTH_EPS) {
cType = Constraint::VERTICAL; cType = Constraint::Type::VERTICAL;
} }
else if(fabs(p0.y - p1.y) < LENGTH_EPS) { else if(fabs(p0.y - p1.y) < LENGTH_EPS) {
cType = Constraint::HORIZONTAL; cType = Constraint::Type::HORIZONTAL;
} }
if(cType != -1) { if(cType != Constraint::Type::UNKNOWN) {
Constraint::Constrain( Constraint::Constrain(
cType, cType,
Entity::NO_ENTITY, Entity::NO_ENTITY,
@ -517,7 +518,7 @@ public:
} }
hEntity createCircle(const Vector &c, double r, uint32_t style) { hEntity createCircle(const Vector &c, double r, uint32_t style) {
hRequest hr = SS.GW.AddRequest(Request::CIRCLE, false); hRequest hr = SS.GW.AddRequest(Request::Type::CIRCLE, false);
SK.GetEntity(hr.entity(1))->PointForceTo(c); SK.GetEntity(hr.entity(1))->PointForceTo(c);
processPoint(hr.entity(1)); processPoint(hr.entity(1));
SK.GetEntity(hr.entity(64))->DistanceForceTo(r); SK.GetEntity(hr.entity(64))->DistanceForceTo(r);
@ -545,7 +546,7 @@ public:
if(data.space != DRW::ModelSpace) return; if(data.space != DRW::ModelSpace) return;
if(addPendingBlockEntity<DRW_Point>(data)) return; if(addPendingBlockEntity<DRW_Point>(data)) return;
hRequest hr = SS.GW.AddRequest(Request::DATUM_POINT, false); hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, false);
SK.GetEntity(hr.entity(0))->PointForceTo(toVector(data.basePoint)); SK.GetEntity(hr.entity(0))->PointForceTo(toVector(data.basePoint));
processPoint(hr.entity(0)); processPoint(hr.entity(0));
} }
@ -561,7 +562,7 @@ public:
if(data.space != DRW::ModelSpace) return; if(data.space != DRW::ModelSpace) return;
if(addPendingBlockEntity<DRW_Arc>(data)) return; if(addPendingBlockEntity<DRW_Arc>(data)) return;
hRequest hr = SS.GW.AddRequest(Request::ARC_OF_CIRCLE, false); hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, false);
double r = data.radious; double r = data.radious;
double sa = data.staangle; double sa = data.staangle;
double ea = data.endangle; double ea = data.endangle;
@ -672,7 +673,7 @@ public:
if(data->degree != 3) return; if(data->degree != 3) return;
if(addPendingBlockEntity<DRW_Spline>(*data)) return; if(addPendingBlockEntity<DRW_Spline>(*data)) return;
hRequest hr = SS.GW.AddRequest(Request::CUBIC, false); hRequest hr = SS.GW.AddRequest(Request::Type::CUBIC, false);
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
SK.GetEntity(hr.entity(i + 1))->PointForceTo(toVector(*data->controllist[i])); SK.GetEntity(hr.entity(i + 1))->PointForceTo(toVector(*data->controllist[i]));
processPoint(hr.entity(i + 1)); processPoint(hr.entity(i + 1));
@ -726,7 +727,7 @@ public:
Constraint c = {}; Constraint c = {};
c.group = SS.GW.activeGroup; c.group = SS.GW.activeGroup;
c.workplane = SS.GW.ActiveWorkplane(); c.workplane = SS.GW.ActiveWorkplane();
c.type = Constraint::COMMENT; c.type = Constraint::Type::COMMENT;
if(data.alignH == DRW_Text::HLeft && data.alignV == DRW_Text::VBaseLine) { if(data.alignH == DRW_Text::HLeft && data.alignV == DRW_Text::VBaseLine) {
c.disp.offset = toVector(data.basePoint); c.disp.offset = toVector(data.basePoint);
} else { } else {
@ -745,7 +746,7 @@ public:
Vector p1 = toVector(data->getDef2Point()); Vector p1 = toVector(data->getDef2Point());
Vector p2 = toVector(data->getTextPoint()); Vector p2 = toVector(data->getTextPoint());
hConstraint hc = Constraint::Constrain( hConstraint hc = Constraint::Constrain(
Constraint::PT_PT_DISTANCE, Constraint::Type::PT_PT_DISTANCE,
createOrGetPoint(p0), createOrGetPoint(p0),
createOrGetPoint(p1), createOrGetPoint(p1),
Entity::NO_ENTITY Entity::NO_ENTITY
@ -784,7 +785,7 @@ public:
p4 = blockTransform(p4); p4 = blockTransform(p4);
hConstraint hc = Constraint::Constrain( hConstraint hc = Constraint::Constrain(
Constraint::PT_LINE_DISTANCE, Constraint::Type::PT_LINE_DISTANCE,
createOrGetPoint(p0), createOrGetPoint(p0),
Entity::NO_ENTITY, Entity::NO_ENTITY,
createLine(p1, p3, invisibleStyle().v) createLine(p1, p3, invisibleStyle().v)
@ -809,7 +810,7 @@ public:
Vector l1p1 = toVector(data->getSecondLine2()); Vector l1p1 = toVector(data->getSecondLine2());
hConstraint hc = Constraint::Constrain( hConstraint hc = Constraint::Constrain(
Constraint::ANGLE, Constraint::Type::ANGLE,
Entity::NO_ENTITY, Entity::NO_ENTITY,
Entity::NO_ENTITY, Entity::NO_ENTITY,
createLine(l0p0, l0p1, invisibleStyle().v), createLine(l0p0, l0p1, invisibleStyle().v),
@ -839,7 +840,7 @@ public:
hEntity he = createCircle(cp, r, invisibleStyle().v); hEntity he = createCircle(cp, r, invisibleStyle().v);
hConstraint hc = Constraint::Constrain( hConstraint hc = Constraint::Constrain(
Constraint::DIAMETER, Constraint::Type::DIAMETER,
Entity::NO_ENTITY, Entity::NO_ENTITY,
Entity::NO_ENTITY, Entity::NO_ENTITY,
he he

View File

@ -103,16 +103,16 @@ void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
EntityBase e = {}; EntityBase e = {};
switch(se->type) { switch(se->type) {
case SLVS_E_POINT_IN_3D: e.type = Entity::POINT_IN_3D; break; case SLVS_E_POINT_IN_3D: e.type = Entity::Type::POINT_IN_3D; break;
case SLVS_E_POINT_IN_2D: e.type = Entity::POINT_IN_2D; break; case SLVS_E_POINT_IN_2D: e.type = Entity::Type::POINT_IN_2D; break;
case SLVS_E_NORMAL_IN_3D: e.type = Entity::NORMAL_IN_3D; break; case SLVS_E_NORMAL_IN_3D: e.type = Entity::Type::NORMAL_IN_3D; break;
case SLVS_E_NORMAL_IN_2D: e.type = Entity::NORMAL_IN_2D; break; case SLVS_E_NORMAL_IN_2D: e.type = Entity::Type::NORMAL_IN_2D; break;
case SLVS_E_DISTANCE: e.type = Entity::DISTANCE; break; case SLVS_E_DISTANCE: e.type = Entity::Type::DISTANCE; break;
case SLVS_E_WORKPLANE: e.type = Entity::WORKPLANE; break; case SLVS_E_WORKPLANE: e.type = Entity::Type::WORKPLANE; break;
case SLVS_E_LINE_SEGMENT: e.type = Entity::LINE_SEGMENT; break; case SLVS_E_LINE_SEGMENT: e.type = Entity::Type::LINE_SEGMENT; break;
case SLVS_E_CUBIC: e.type = Entity::CUBIC; break; case SLVS_E_CUBIC: e.type = Entity::Type::CUBIC; break;
case SLVS_E_CIRCLE: e.type = Entity::CIRCLE; break; case SLVS_E_CIRCLE: e.type = Entity::Type::CIRCLE; break;
case SLVS_E_ARC_OF_CIRCLE: e.type = Entity::ARC_OF_CIRCLE; break; case SLVS_E_ARC_OF_CIRCLE: e.type = Entity::Type::ARC_OF_CIRCLE; break;
default: dbp("bad entity type %d", se->type); return; default: dbp("bad entity type %d", se->type); return;
} }
@ -137,42 +137,42 @@ default: dbp("bad entity type %d", se->type); return;
Slvs_Constraint *sc = &(ssys->constraint[i]); Slvs_Constraint *sc = &(ssys->constraint[i]);
ConstraintBase c = {}; ConstraintBase c = {};
int t; Constraint::Type t;
switch(sc->type) { switch(sc->type) {
case SLVS_C_POINTS_COINCIDENT: t = Constraint::POINTS_COINCIDENT; break; case SLVS_C_POINTS_COINCIDENT: t = Constraint::Type::POINTS_COINCIDENT; break;
case SLVS_C_PT_PT_DISTANCE: t = Constraint::PT_PT_DISTANCE; break; case SLVS_C_PT_PT_DISTANCE: t = Constraint::Type::PT_PT_DISTANCE; break;
case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::PT_PLANE_DISTANCE; break; case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::Type::PT_PLANE_DISTANCE; break;
case SLVS_C_PT_LINE_DISTANCE: t = Constraint::PT_LINE_DISTANCE; break; case SLVS_C_PT_LINE_DISTANCE: t = Constraint::Type::PT_LINE_DISTANCE; break;
case SLVS_C_PT_FACE_DISTANCE: t = Constraint::PT_FACE_DISTANCE; break; case SLVS_C_PT_FACE_DISTANCE: t = Constraint::Type::PT_FACE_DISTANCE; break;
case SLVS_C_PT_IN_PLANE: t = Constraint::PT_IN_PLANE; break; case SLVS_C_PT_IN_PLANE: t = Constraint::Type::PT_IN_PLANE; break;
case SLVS_C_PT_ON_LINE: t = Constraint::PT_ON_LINE; break; case SLVS_C_PT_ON_LINE: t = Constraint::Type::PT_ON_LINE; break;
case SLVS_C_PT_ON_FACE: t = Constraint::PT_ON_FACE; break; case SLVS_C_PT_ON_FACE: t = Constraint::Type::PT_ON_FACE; break;
case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::EQUAL_LENGTH_LINES; break; case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::Type::EQUAL_LENGTH_LINES; break;
case SLVS_C_LENGTH_RATIO: t = Constraint::LENGTH_RATIO; break; case SLVS_C_LENGTH_RATIO: t = Constraint::Type::LENGTH_RATIO; break;
case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::EQ_LEN_PT_LINE_D; break; case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::Type::EQ_LEN_PT_LINE_D; break;
case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::EQ_PT_LN_DISTANCES; break; case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::Type::EQ_PT_LN_DISTANCES; break;
case SLVS_C_EQUAL_ANGLE: t = Constraint::EQUAL_ANGLE; break; case SLVS_C_EQUAL_ANGLE: t = Constraint::Type::EQUAL_ANGLE; break;
case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::EQUAL_LINE_ARC_LEN; break; case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::Type::EQUAL_LINE_ARC_LEN; break;
case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::LENGTH_DIFFERENCE; break; case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::Type::LENGTH_DIFFERENCE; break;
case SLVS_C_SYMMETRIC: t = Constraint::SYMMETRIC; break; case SLVS_C_SYMMETRIC: t = Constraint::Type::SYMMETRIC; break;
case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::SYMMETRIC_HORIZ; break; case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::Type::SYMMETRIC_HORIZ; break;
case SLVS_C_SYMMETRIC_VERT: t = Constraint::SYMMETRIC_VERT; break; case SLVS_C_SYMMETRIC_VERT: t = Constraint::Type::SYMMETRIC_VERT; break;
case SLVS_C_SYMMETRIC_LINE: t = Constraint::SYMMETRIC_LINE; break; case SLVS_C_SYMMETRIC_LINE: t = Constraint::Type::SYMMETRIC_LINE; break;
case SLVS_C_AT_MIDPOINT: t = Constraint::AT_MIDPOINT; break; case SLVS_C_AT_MIDPOINT: t = Constraint::Type::AT_MIDPOINT; break;
case SLVS_C_HORIZONTAL: t = Constraint::HORIZONTAL; break; case SLVS_C_HORIZONTAL: t = Constraint::Type::HORIZONTAL; break;
case SLVS_C_VERTICAL: t = Constraint::VERTICAL; break; case SLVS_C_VERTICAL: t = Constraint::Type::VERTICAL; break;
case SLVS_C_DIAMETER: t = Constraint::DIAMETER; break; case SLVS_C_DIAMETER: t = Constraint::Type::DIAMETER; break;
case SLVS_C_PT_ON_CIRCLE: t = Constraint::PT_ON_CIRCLE; break; case SLVS_C_PT_ON_CIRCLE: t = Constraint::Type::PT_ON_CIRCLE; break;
case SLVS_C_SAME_ORIENTATION: t = Constraint::SAME_ORIENTATION; break; case SLVS_C_SAME_ORIENTATION: t = Constraint::Type::SAME_ORIENTATION; break;
case SLVS_C_ANGLE: t = Constraint::ANGLE; break; case SLVS_C_ANGLE: t = Constraint::Type::ANGLE; break;
case SLVS_C_PARALLEL: t = Constraint::PARALLEL; break; case SLVS_C_PARALLEL: t = Constraint::Type::PARALLEL; break;
case SLVS_C_PERPENDICULAR: t = Constraint::PERPENDICULAR; break; case SLVS_C_PERPENDICULAR: t = Constraint::Type::PERPENDICULAR; break;
case SLVS_C_ARC_LINE_TANGENT: t = Constraint::ARC_LINE_TANGENT; break; case SLVS_C_ARC_LINE_TANGENT: t = Constraint::Type::ARC_LINE_TANGENT; break;
case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::CUBIC_LINE_TANGENT; break; case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::Type::CUBIC_LINE_TANGENT; break;
case SLVS_C_EQUAL_RADIUS: t = Constraint::EQUAL_RADIUS; break; case SLVS_C_EQUAL_RADIUS: t = Constraint::Type::EQUAL_RADIUS; break;
case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::PROJ_PT_DISTANCE; break; case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::Type::PROJ_PT_DISTANCE; break;
case SLVS_C_WHERE_DRAGGED: t = Constraint::WHERE_DRAGGED; break; case SLVS_C_WHERE_DRAGGED: t = Constraint::Type::WHERE_DRAGGED; break;
case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::CURVE_CURVE_TANGENT; break; case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::Type::CURVE_CURVE_TANGENT; break;
default: dbp("bad constraint type %d", sc->type); return; default: dbp("bad constraint type %d", sc->type); return;
} }
@ -209,23 +209,23 @@ default: dbp("bad constraint type %d", sc->type); return;
// Now we're finally ready to solve! // Now we're finally ready to solve!
bool andFindBad = ssys->calculateFaileds ? true : false; bool andFindBad = ssys->calculateFaileds ? true : false;
int how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false); SolveResult how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false);
switch(how) { switch(how) {
case System::SOLVED_OKAY: case SolveResult::OKAY:
ssys->result = SLVS_RESULT_OKAY; ssys->result = SLVS_RESULT_OKAY;
break; break;
case System::DIDNT_CONVERGE: case SolveResult::DIDNT_CONVERGE:
ssys->result = SLVS_RESULT_DIDNT_CONVERGE; ssys->result = SLVS_RESULT_DIDNT_CONVERGE;
break; break;
case System::REDUNDANT_DIDNT_CONVERGE: case SolveResult::REDUNDANT_DIDNT_CONVERGE:
case System::REDUNDANT_OKAY: case SolveResult::REDUNDANT_OKAY:
ssys->result = SLVS_RESULT_INCONSISTENT; ssys->result = SLVS_RESULT_INCONSISTENT;
break; break;
case System::TOO_MANY_UNKNOWNS: case SolveResult::TOO_MANY_UNKNOWNS:
ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS; ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS;
break; break;

View File

@ -85,13 +85,13 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
// Select the naked edges in our resulting open mesh. // Select the naked edges in our resulting open mesh.
SKdNode *root = SKdNode::From(&m); SKdNode *root = SKdNode::From(&m);
root->SnapToMesh(&m); root->SnapToMesh(&m);
root->MakeCertainEdgesInto(sel, SKdNode::NAKED_OR_SELF_INTER_EDGES, root->MakeCertainEdgesInto(sel, EdgeKind::NAKED_OR_SELF_INTER,
false, NULL, NULL); false, NULL, NULL);
m.Clear(); m.Clear();
} }
void SMesh::MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, int type) { void SMesh::MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, EdgeKind type) {
SKdNode *root = SKdNode::From(this); SKdNode *root = SKdNode::From(this);
root->MakeCertainEdgesInto(sel, type, false, NULL, NULL); root->MakeCertainEdgesInto(sel, type, false, NULL, NULL);
root->MakeOutlinesInto(sol); root->MakeOutlinesInto(sol);
@ -924,7 +924,7 @@ static bool CheckAndAddTrianglePair(std::set<std::pair<STriangle *, STriangle *>
// * emphasized edges (i.e., edges where a triangle from one face joins // * emphasized edges (i.e., edges where a triangle from one face joins
// a triangle from a different face) // a triangle from a different face)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter, void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter,
bool *inter, bool *leaky, int auxA) const bool *inter, bool *leaky, int auxA) const
{ {
if(inter) *inter = false; if(inter) *inter = false;
@ -945,7 +945,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
FindEdgeOn(a, b, cnt, coplanarIsInter, &info); FindEdgeOn(a, b, cnt, coplanarIsInter, &info);
switch(how) { switch(how) {
case NAKED_OR_SELF_INTER_EDGES: case EdgeKind::NAKED_OR_SELF_INTER:
if(info.count != 1) { if(info.count != 1) {
sel->AddEdge(a, b, auxA); sel->AddEdge(a, b, auxA);
if(leaky) *leaky = true; if(leaky) *leaky = true;
@ -956,14 +956,14 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
} }
break; break;
case SELF_INTER_EDGES: case EdgeKind::SELF_INTER:
if(info.intersectsMesh) { if(info.intersectsMesh) {
sel->AddEdge(a, b, auxA); sel->AddEdge(a, b, auxA);
if(inter) *inter = true; if(inter) *inter = true;
} }
break; break;
case TURNING_EDGES: case EdgeKind::TURNING:
if((tr->Normal().z < LENGTH_EPS) && if((tr->Normal().z < LENGTH_EPS) &&
(info.count == 1) && (info.count == 1) &&
info.frontFacing) info.frontFacing)
@ -977,7 +977,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
} }
break; break;
case EMPHASIZED_EDGES: case EdgeKind::EMPHASIZED:
if(info.count == 1 && tr->meta.face != info.tr->meta.face) { if(info.count == 1 && tr->meta.face != info.tr->meta.face) {
if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr)) if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr))
break; break;
@ -989,7 +989,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
} }
break; break;
case SHARP_EDGES: case EdgeKind::SHARP:
if(info.count == 1) { if(info.count == 1) {
Vector na0 = (j == 0) ? tr->an : Vector na0 = (j == 0) ? tr->an :
((j == 1) ? tr->bn : tr->cn); ((j == 1) ? tr->bn : tr->cn);

View File

@ -30,9 +30,9 @@ void GraphicsWindow::RemoveConstraintsForPointBeingDeleted(hEntity hpt) {
if(c->ptA.v == hpt.v || c->ptB.v == hpt.v) { if(c->ptA.v == hpt.v || c->ptB.v == hpt.v) {
c->tag = 1; c->tag = 1;
(SS.deleted.constraints)++; (SS.deleted.constraints)++;
if(c->type != Constraint::POINTS_COINCIDENT && if(c->type != Constraint::Type::POINTS_COINCIDENT &&
c->type != Constraint::HORIZONTAL && c->type != Constraint::Type::HORIZONTAL &&
c->type != Constraint::VERTICAL) c->type != Constraint::Type::VERTICAL)
{ {
(SS.deleted.nonTrivialConstraints)++; (SS.deleted.nonTrivialConstraints)++;
} }
@ -56,8 +56,8 @@ void GraphicsWindow::FixConstraintsForRequestBeingDeleted(hRequest hr) {
if(!(e->h.isFromRequest())) continue; if(!(e->h.isFromRequest())) continue;
if(e->h.request().v != hr.v) continue; if(e->h.request().v != hr.v) continue;
if(e->type != Entity::POINT_IN_2D && if(e->type != Entity::Type::POINT_IN_2D &&
e->type != Entity::POINT_IN_3D) e->type != Entity::Type::POINT_IN_3D)
{ {
continue; continue;
} }
@ -73,7 +73,7 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
Constraint *c; Constraint *c;
SK.constraint.ClearTags(); SK.constraint.ClearTags();
for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) { for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
if(c->type != Constraint::POINTS_COINCIDENT) continue; if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
if(c->group.v != SS.GW.activeGroup.v) continue; if(c->group.v != SS.GW.activeGroup.v) continue;
if(c->ptA.v == hpt.v) { if(c->ptA.v == hpt.v) {
@ -111,14 +111,14 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
void GraphicsWindow::ParametricCurve::MakeFromEntity(hEntity he, bool reverse) { void GraphicsWindow::ParametricCurve::MakeFromEntity(hEntity he, bool reverse) {
*this = {}; *this = {};
Entity *e = SK.GetEntity(he); Entity *e = SK.GetEntity(he);
if(e->type == Entity::LINE_SEGMENT) { if(e->type == Entity::Type::LINE_SEGMENT) {
isLine = true; isLine = true;
p0 = e->EndpointStart(), p0 = e->EndpointStart(),
p1 = e->EndpointFinish(); p1 = e->EndpointFinish();
if(reverse) { if(reverse) {
swap(p0, p1); swap(p0, p1);
} }
} else if(e->type == Entity::ARC_OF_CIRCLE) { } else if(e->type == Entity::Type::ARC_OF_CIRCLE) {
isLine = false; isLine = false;
p0 = SK.GetEntity(e->point[0])->PointGetNum(); p0 = SK.GetEntity(e->point[0])->PointGetNum();
Vector pe = SK.GetEntity(e->point[1])->PointGetNum(); Vector pe = SK.GetEntity(e->point[1])->PointGetNum();
@ -167,21 +167,21 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
hRequest hr; hRequest hr;
Entity *e; Entity *e;
if(isLine) { if(isLine) {
hr = SS.GW.AddRequest(Request::LINE_SEGMENT, false), hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, false),
e = SK.GetEntity(hr.entity(0)); e = SK.GetEntity(hr.entity(0));
SK.GetEntity(e->point[0])->PointForceTo(PointAt(t)); SK.GetEntity(e->point[0])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1)); SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
ConstrainPointIfCoincident(e->point[0]); ConstrainPointIfCoincident(e->point[0]);
ConstrainPointIfCoincident(e->point[1]); ConstrainPointIfCoincident(e->point[1]);
if(extraConstraints) { if(extraConstraints) {
Constraint::Constrain(Constraint::PT_ON_LINE, Constraint::Constrain(Constraint::Type::PT_ON_LINE,
hr.entity(1), Entity::NO_ENTITY, orig); hr.entity(1), Entity::NO_ENTITY, orig);
} }
Constraint::Constrain(Constraint::ARC_LINE_TANGENT, Constraint::Constrain(Constraint::Type::ARC_LINE_TANGENT,
Entity::NO_ENTITY, Entity::NO_ENTITY, Entity::NO_ENTITY, Entity::NO_ENTITY,
arc, e->h, arcFinish, false); arc, e->h, arcFinish, false);
} else { } else {
hr = SS.GW.AddRequest(Request::ARC_OF_CIRCLE, false), hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, false),
e = SK.GetEntity(hr.entity(0)); e = SK.GetEntity(hr.entity(0));
SK.GetEntity(e->point[0])->PointForceTo(p0); SK.GetEntity(e->point[0])->PointForceTo(p0);
if(dtheta > 0) { if(dtheta > 0) {
@ -196,7 +196,7 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
ConstrainPointIfCoincident(e->point[2]); ConstrainPointIfCoincident(e->point[2]);
// The tangency constraint alone is enough to fully constrain it, // The tangency constraint alone is enough to fully constrain it,
// so there's no need for more. // so there's no need for more.
Constraint::Constrain(Constraint::CURVE_CURVE_TANGENT, Constraint::Constrain(Constraint::Type::CURVE_CURVE_TANGENT,
Entity::NO_ENTITY, Entity::NO_ENTITY, Entity::NO_ENTITY, Entity::NO_ENTITY,
arc, e->h, arcFinish, (dtheta < 0)); arc, e->h, arcFinish, (dtheta < 0));
} }
@ -257,8 +257,8 @@ void GraphicsWindow::MakeTangentArc() {
if(r->group.v != activeGroup.v) continue; if(r->group.v != activeGroup.v) continue;
if(r->workplane.v != ActiveWorkplane().v) continue; if(r->workplane.v != ActiveWorkplane().v) continue;
if(r->construction) continue; if(r->construction) continue;
if(r->type != Request::LINE_SEGMENT && if(r->type != Request::Type::LINE_SEGMENT &&
r->type != Request::ARC_OF_CIRCLE) r->type != Request::Type::ARC_OF_CIRCLE)
{ {
continue; continue;
} }
@ -389,7 +389,7 @@ void GraphicsWindow::MakeTangentArc() {
SS.UndoRemember(); SS.UndoRemember();
hRequest harc = AddRequest(Request::ARC_OF_CIRCLE, false); hRequest harc = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
Entity *earc = SK.GetEntity(harc.entity(0)); Entity *earc = SK.GetEntity(harc.entity(0));
hEntity hearc = earc->h; hEntity hearc = earc->h;
@ -432,8 +432,8 @@ hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
p1 = SK.GetEntity(hep1)->PointGetNum(); p1 = SK.GetEntity(hep1)->PointGetNum();
// Add the two line segments this one gets split into. // Add the two line segments this one gets split into.
hRequest r0i = AddRequest(Request::LINE_SEGMENT, false), hRequest r0i = AddRequest(Request::Type::LINE_SEGMENT, false),
ri1 = AddRequest(Request::LINE_SEGMENT, false); ri1 = AddRequest(Request::Type::LINE_SEGMENT, false);
// Don't get entities till after adding, realloc issues // Don't get entities till after adding, realloc issues
Entity *e0i = SK.GetEntity(r0i.entity(0)), Entity *e0i = SK.GetEntity(r0i.entity(0)),
@ -452,12 +452,12 @@ hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) { hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
Entity *circle = SK.GetEntity(he); Entity *circle = SK.GetEntity(he);
if(circle->type == Entity::CIRCLE) { if(circle->type == Entity::Type::CIRCLE) {
// Start with an unbroken circle, split it into a 360 degree arc. // Start with an unbroken circle, split it into a 360 degree arc.
Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
circle = NULL; // shortly invalid! circle = NULL; // shortly invalid!
hRequest hr = AddRequest(Request::ARC_OF_CIRCLE, false); hRequest hr = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
Entity *arc = SK.GetEntity(hr.entity(0)); Entity *arc = SK.GetEntity(hr.entity(0));
@ -477,8 +477,8 @@ hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
finish = SK.GetEntity(hf)->PointGetNum(); finish = SK.GetEntity(hf)->PointGetNum();
circle = NULL; // shortly invalid! circle = NULL; // shortly invalid!
hRequest hr0 = AddRequest(Request::ARC_OF_CIRCLE, false), hRequest hr0 = AddRequest(Request::Type::ARC_OF_CIRCLE, false),
hr1 = AddRequest(Request::ARC_OF_CIRCLE, false); hr1 = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
Entity *arc0 = SK.GetEntity(hr0.entity(0)), Entity *arc0 = SK.GetEntity(hr0.entity(0)),
*arc1 = SK.GetEntity(hr1.entity(0)); *arc1 = SK.GetEntity(hr1.entity(0));
@ -525,8 +525,8 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
b01.SplitAt(t, &b0i, &bi1); b01.SplitAt(t, &b0i, &bi1);
// Add the two cubic segments this one gets split into. // Add the two cubic segments this one gets split into.
hRequest r0i = AddRequest(Request::CUBIC, false), hRequest r0i = AddRequest(Request::Type::CUBIC, false),
ri1 = AddRequest(Request::CUBIC, false); ri1 = AddRequest(Request::Type::CUBIC, false);
// Don't get entities till after adding, realloc issues // Don't get entities till after adding, realloc issues
Entity *e0i = SK.GetEntity(r0i.entity(0)), Entity *e0i = SK.GetEntity(r0i.entity(0)),
@ -544,7 +544,7 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
hep1n = ei1->point[3]; hep1n = ei1->point[3];
hepin = e0i->point[3]; hepin = e0i->point[3];
} else { } else {
hRequest r = AddRequest(Request::CUBIC, false); hRequest r = AddRequest(Request::Type::CUBIC, false);
Entity *e = SK.GetEntity(r.entity(0)); Entity *e = SK.GetEntity(r.entity(0));
for(j = 0; j <= 3; j++) { for(j = 0; j <= 3; j++) {
@ -565,14 +565,14 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) { hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
Entity *e = SK.GetEntity(he); Entity *e = SK.GetEntity(he);
int entityType = e->type; Entity::Type entityType = e->type;
hEntity ret; hEntity ret;
if(e->IsCircle()) { if(e->IsCircle()) {
ret = SplitCircle(he, pinter); ret = SplitCircle(he, pinter);
} else if(e->type == Entity::LINE_SEGMENT) { } else if(e->type == Entity::Type::LINE_SEGMENT) {
ret = SplitLine(he, pinter); ret = SplitLine(he, pinter);
} else if(e->type == Entity::CUBIC || e->type == Entity::CUBIC_PERIODIC) { } else if(e->type == Entity::Type::CUBIC || e->type == Entity::Type::CUBIC_PERIODIC) {
ret = SplitCubic(he, pinter); ret = SplitCubic(he, pinter);
} else { } else {
Error("Couldn't split this entity; lines, circles, or cubics only."); Error("Couldn't split this entity; lines, circles, or cubics only.");
@ -580,7 +580,7 @@ hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
} }
// Finally, delete the request that generated the original entity. // Finally, delete the request that generated the original entity.
int reqType = EntReqTable::GetRequestForEntity(entityType); Request::Type reqType = EntReqTable::GetRequestForEntity(entityType);
SK.request.ClearTags(); SK.request.ClearTags();
for(int i = 0; i < SK.request.n; i++) { for(int i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]); Request *r = &(SK.request.elem[i]);

View File

@ -30,8 +30,8 @@ void GraphicsWindow::AddPointToDraggedList(hEntity hp) {
} }
Entity *pe = SK.GetEntity(*hee); Entity *pe = SK.GetEntity(*hee);
if(pe->type == p->type && if(pe->type == p->type &&
pe->type != Entity::POINT_IN_2D && pe->type != Entity::Type::POINT_IN_2D &&
pe->type != Entity::POINT_IN_3D && pe->type != Entity::Type::POINT_IN_3D &&
pe->group.v == p->group.v) pe->group.v == p->group.v)
{ {
// Transform-type point, from the same group. So it handles the // Transform-type point, from the same group. So it handles the
@ -46,12 +46,12 @@ void GraphicsWindow::StartDraggingByEntity(hEntity he) {
Entity *e = SK.GetEntity(he); Entity *e = SK.GetEntity(he);
if(e->IsPoint()) { if(e->IsPoint()) {
AddPointToDraggedList(e->h); AddPointToDraggedList(e->h);
} else if(e->type == Entity::LINE_SEGMENT || } else if(e->type == Entity::Type::LINE_SEGMENT ||
e->type == Entity::ARC_OF_CIRCLE || e->type == Entity::Type::ARC_OF_CIRCLE ||
e->type == Entity::CUBIC || e->type == Entity::Type::CUBIC ||
e->type == Entity::CUBIC_PERIODIC || e->type == Entity::Type::CUBIC_PERIODIC ||
e->type == Entity::CIRCLE || e->type == Entity::Type::CIRCLE ||
e->type == Entity::TTF_TEXT) e->type == Entity::Type::TTF_TEXT)
{ {
int pts; int pts;
EntReqTable::GetEntityInfo(e->type, e->extraPoints, EntReqTable::GetEntityInfo(e->type, e->extraPoints,
@ -157,7 +157,7 @@ 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(SS.TW.shown.screen == TextWindow::Screen::EDIT_VIEW) {
if(havePainted) { if(havePainted) {
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
@ -174,9 +174,9 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
if(leftDown && dm > 3) { if(leftDown && dm > 3) {
Entity *e = NULL; Entity *e = NULL;
if(hover.entity.v) e = SK.GetEntity(hover.entity); if(hover.entity.v) e = SK.GetEntity(hover.entity);
if(e && e->type != Entity::WORKPLANE) { if(e && e->type != Entity::Type::WORKPLANE) {
Entity *e = SK.GetEntity(hover.entity); Entity *e = SK.GetEntity(hover.entity);
if(e->type == Entity::CIRCLE && selection.n <= 1) { if(e->type == Entity::Type::CIRCLE && selection.n <= 1) {
// Drag the radius. // Drag the radius.
ClearSelection(); ClearSelection();
pending.circle = hover.entity; pending.circle = hover.entity;
@ -284,7 +284,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
SS.GW.pending.suggestion = SS.GW.pending.suggestion =
SS.GW.SuggestLineConstraint(SS.GW.pending.request); SS.GW.SuggestLineConstraint(SS.GW.pending.request);
} else { } else {
SS.GW.pending.suggestion = SUGGESTED_NONE; SS.GW.pending.suggestion = Constraint::Type::UNKNOWN;
} }
case DRAGGING_NEW_POINT: case DRAGGING_NEW_POINT:
UpdateDraggedPoint(pending.point, x, y); UpdateDraggedPoint(pending.point, x, y);
@ -333,7 +333,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
List<hEntity> *lhe = &(pending.points); List<hEntity> *lhe = &(pending.points);
for(hEntity *he = lhe->First(); he; he = lhe->NextAfter(he)) { for(hEntity *he = lhe->First(); he; he = lhe->NextAfter(he)) {
Entity *e = SK.GetEntity(*he); Entity *e = SK.GetEntity(*he);
if(e->type != Entity::POINT_N_ROT_TRANS) { if(e->type != Entity::Type::POINT_N_ROT_TRANS) {
if(ctrlDown) { if(ctrlDown) {
Vector p = e->PointGetNum(); Vector p = e->PointGetNum();
p = p.Minus(SS.extraLine.ptA); p = p.Minus(SS.extraLine.ptA);
@ -490,14 +490,14 @@ void GraphicsWindow::ContextMenuListStyles() {
for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) { for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) {
if(s->h.v < Style::FIRST_CUSTOM) continue; if(s->h.v < Style::FIRST_CUSTOM) continue;
AddContextMenuItem(s->DescriptionString().c_str(), CMNU_FIRST_STYLE + s->h.v); AddContextMenuItem(s->DescriptionString().c_str(), (ContextCommand)((uint32_t)ContextCommand::FIRST_STYLE + s->h.v));
empty = false; empty = false;
} }
if(!empty) AddContextMenuItem(NULL, CONTEXT_SEPARATOR); if(!empty) AddContextMenuItem(NULL, ContextCommand::SEPARATOR);
AddContextMenuItem("No Style", CMNU_NO_STYLE); AddContextMenuItem("No Style", ContextCommand::NO_STYLE);
AddContextMenuItem("Newly Created Custom Style...", CMNU_NEW_CUSTOM_STYLE); AddContextMenuItem("Newly Created Custom Style...", ContextCommand::NEW_CUSTOM_STYLE);
} }
void GraphicsWindow::MouseRightUp(double x, double y) { void GraphicsWindow::MouseRightUp(double x, double y) {
@ -512,7 +512,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
if(context.active) return; if(context.active) return;
if(pending.operation == DRAGGING_NEW_LINE_POINT) { if(pending.operation == DRAGGING_NEW_LINE_POINT) {
if(SS.GW.pending.suggestion != SUGGESTED_NONE) { if(SS.GW.pending.suggestion != Constraint::Type::UNKNOWN) {
Constraint::Constrain(SS.GW.pending.suggestion, Constraint::Constrain(SS.GW.pending.suggestion,
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0)); Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
} }
@ -547,53 +547,53 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
if(itemsSelected) { if(itemsSelected) {
if(gs.stylables > 0) { if(gs.stylables > 0) {
ContextMenuListStyles(); ContextMenuListStyles();
AddContextMenuItem("Assign to Style", CONTEXT_SUBMENU); AddContextMenuItem("Assign to Style", ContextCommand::SUBMENU);
} }
if(gs.n + gs.constraints == 1) { if(gs.n + gs.constraints == 1) {
AddContextMenuItem("Group Info", CMNU_GROUP_INFO); AddContextMenuItem("Group Info", ContextCommand::GROUP_INFO);
} }
if(gs.n + gs.constraints == 1 && gs.stylables == 1) { if(gs.n + gs.constraints == 1 && gs.stylables == 1) {
AddContextMenuItem("Style Info", CMNU_STYLE_INFO); AddContextMenuItem("Style Info", ContextCommand::STYLE_INFO);
} }
if(gs.withEndpoints > 0) { if(gs.withEndpoints > 0) {
AddContextMenuItem("Select Edge Chain", CMNU_SELECT_CHAIN); AddContextMenuItem("Select Edge Chain", ContextCommand::SELECT_CHAIN);
} }
if(gs.constraints == 1 && gs.n == 0) { if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SK.GetConstraint(gs.constraint[0]); Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->HasLabel() && c->type != Constraint::COMMENT) { if(c->HasLabel() && c->type != Constraint::Type::COMMENT) {
AddContextMenuItem("Toggle Reference Dimension", AddContextMenuItem("Toggle Reference Dimension",
CMNU_REFERENCE_DIM); ContextCommand::REFERENCE_DIM);
} }
if(c->type == Constraint::ANGLE || if(c->type == Constraint::Type::ANGLE ||
c->type == Constraint::EQUAL_ANGLE) c->type == Constraint::Type::EQUAL_ANGLE)
{ {
AddContextMenuItem("Other Supplementary Angle", AddContextMenuItem("Other Supplementary Angle",
CMNU_OTHER_ANGLE); ContextCommand::OTHER_ANGLE);
} }
} }
if(gs.constraintLabels > 0 || gs.points > 0) { if(gs.constraintLabels > 0 || gs.points > 0) {
AddContextMenuItem("Snap to Grid", CMNU_SNAP_TO_GRID); AddContextMenuItem("Snap to Grid", ContextCommand::SNAP_TO_GRID);
} }
if(gs.points == 1 && gs.point[0].isFromRequest()) { if(gs.points == 1 && gs.point[0].isFromRequest()) {
Request *r = SK.GetRequest(gs.point[0].request()); Request *r = SK.GetRequest(gs.point[0].request());
int index = r->IndexOfPoint(gs.point[0]); int index = r->IndexOfPoint(gs.point[0]);
if((r->type == Request::CUBIC && (index > 1 && index < r->extraPoints + 2)) || if((r->type == Request::Type::CUBIC && (index > 1 && index < r->extraPoints + 2)) ||
r->type == Request::CUBIC_PERIODIC) { r->type == Request::Type::CUBIC_PERIODIC) {
AddContextMenuItem("Remove Spline Point", CMNU_REMOVE_SPLINE_PT); AddContextMenuItem("Remove Spline Point", ContextCommand::REMOVE_SPLINE_PT);
} }
} }
if(gs.entities == 1 && gs.entity[0].isFromRequest()) { if(gs.entities == 1 && gs.entity[0].isFromRequest()) {
Request *r = SK.GetRequest(gs.entity[0].request()); Request *r = SK.GetRequest(gs.entity[0].request());
if(r->type == Request::CUBIC || r->type == Request::CUBIC_PERIODIC) { if(r->type == Request::Type::CUBIC || r->type == Request::Type::CUBIC_PERIODIC) {
Entity *e = SK.GetEntity(gs.entity[0]); Entity *e = SK.GetEntity(gs.entity[0]);
e->GetDistance(Point2d::From(x, y)); e->GetDistance(Point2d::From(x, y));
addAfterPoint = e->dogd.data; addAfterPoint = e->dogd.data;
ssassert(addAfterPoint != -1, "Expected a nearest bezier point to be located"); ssassert(addAfterPoint != -1, "Expected a nearest bezier point to be located");
// Skip derivative point. // Skip derivative point.
if(r->type == Request::CUBIC) addAfterPoint++; if(r->type == Request::Type::CUBIC) addAfterPoint++;
AddContextMenuItem("Add Spline Point", CMNU_ADD_SPLINE_PT); AddContextMenuItem("Add Spline Point", ContextCommand::ADD_SPLINE_PT);
} }
} }
@ -602,85 +602,90 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
Constraint *c; Constraint *c;
IdList<Constraint,hConstraint> *lc = &(SK.constraint); IdList<Constraint,hConstraint> *lc = &(SK.constraint);
for(c = lc->First(); c; c = lc->NextAfter(c)) { for(c = lc->First(); c; c = lc->NextAfter(c)) {
if(c->type != Constraint::POINTS_COINCIDENT) continue; if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
if(c->ptA.v == p->h.v || c->ptB.v == p->h.v) { if(c->ptA.v == p->h.v || c->ptB.v == p->h.v) {
break; break;
} }
} }
if(c) { if(c) {
AddContextMenuItem("Delete Point-Coincident Constraint", AddContextMenuItem("Delete Point-Coincident Constraint",
CMNU_DEL_COINCIDENT); ContextCommand::DEL_COINCIDENT);
} }
} }
AddContextMenuItem(NULL, CONTEXT_SEPARATOR); AddContextMenuItem(NULL, ContextCommand::SEPARATOR);
if(LockedInWorkplane()) { if(LockedInWorkplane()) {
AddContextMenuItem("Cut", CMNU_CUT_SEL); AddContextMenuItem("Cut", ContextCommand::CUT_SEL);
AddContextMenuItem("Copy", CMNU_COPY_SEL); AddContextMenuItem("Copy", ContextCommand::COPY_SEL);
} }
} }
if(SS.clipboard.r.n > 0 && LockedInWorkplane()) { if(SS.clipboard.r.n > 0 && LockedInWorkplane()) {
AddContextMenuItem("Paste", CMNU_PASTE); AddContextMenuItem("Paste", ContextCommand::PASTE);
AddContextMenuItem("Paste Transformed...", CMNU_PASTE_XFRM); AddContextMenuItem("Paste Transformed...", ContextCommand::PASTE_XFRM);
} }
if(itemsSelected) { if(itemsSelected) {
AddContextMenuItem("Delete", CMNU_DELETE_SEL); AddContextMenuItem("Delete", ContextCommand::DELETE_SEL);
AddContextMenuItem(NULL, CONTEXT_SEPARATOR); AddContextMenuItem(NULL, ContextCommand::SEPARATOR);
AddContextMenuItem("Unselect All", CMNU_UNSELECT_ALL); AddContextMenuItem("Unselect All", ContextCommand::UNSELECT_ALL);
} }
// If only one item is selected, then it must be the one that we just // If only one item is selected, then it must be the one that we just
// selected from the hovered item; in which case unselect all and hovered // selected from the hovered item; in which case unselect all and hovered
// are equivalent. // are equivalent.
if(!hover.IsEmpty() && selection.n > 1) { if(!hover.IsEmpty() && selection.n > 1) {
AddContextMenuItem("Unselect Hovered", CMNU_UNSELECT_HOVERED); AddContextMenuItem("Unselect Hovered", ContextCommand::UNSELECT_HOVERED);
} }
int ret = ShowContextMenu(); ContextCommand ret = ShowContextMenu();
switch(ret) { switch(ret) {
case CMNU_UNSELECT_ALL: case ContextCommand::CANCELLED:
MenuEdit(MNU_UNSELECT_ALL); // otherwise it was cancelled, so do nothing
contextMenuCancelTime = GetMilliseconds();
break; break;
case CMNU_UNSELECT_HOVERED: case ContextCommand::UNSELECT_ALL:
MenuEdit(Command::UNSELECT_ALL);
break;
case ContextCommand::UNSELECT_HOVERED:
if(!hover.IsEmpty()) { if(!hover.IsEmpty()) {
MakeUnselected(&hover, true); MakeUnselected(&hover, true);
} }
break; break;
case CMNU_SELECT_CHAIN: case ContextCommand::SELECT_CHAIN:
MenuEdit(MNU_SELECT_CHAIN); MenuEdit(Command::SELECT_CHAIN);
break; break;
case CMNU_CUT_SEL: case ContextCommand::CUT_SEL:
MenuClipboard(MNU_CUT); MenuClipboard(Command::CUT);
break; break;
case CMNU_COPY_SEL: case ContextCommand::COPY_SEL:
MenuClipboard(MNU_COPY); MenuClipboard(Command::COPY);
break; break;
case CMNU_PASTE: case ContextCommand::PASTE:
MenuClipboard(MNU_PASTE); MenuClipboard(Command::PASTE);
break; break;
case CMNU_PASTE_XFRM: case ContextCommand::PASTE_XFRM:
MenuClipboard(MNU_PASTE_TRANSFORM); MenuClipboard(Command::PASTE_TRANSFORM);
break; break;
case CMNU_DELETE_SEL: case ContextCommand::DELETE_SEL:
MenuClipboard(MNU_DELETE); MenuClipboard(Command::DELETE);
break; break;
case CMNU_REFERENCE_DIM: case ContextCommand::REFERENCE_DIM:
Constraint::MenuConstrain(MNU_REFERENCE); Constraint::MenuConstrain(Command::REFERENCE);
break; break;
case CMNU_OTHER_ANGLE: case ContextCommand::OTHER_ANGLE:
Constraint::MenuConstrain(MNU_OTHER_ANGLE); Constraint::MenuConstrain(Command::OTHER_ANGLE);
break; break;
case CMNU_DEL_COINCIDENT: { case ContextCommand::DEL_COINCIDENT: {
SS.UndoRemember(); SS.UndoRemember();
if(!gs.point[0].v) break; if(!gs.point[0].v) break;
Entity *p = SK.GetEntity(gs.point[0]); Entity *p = SK.GetEntity(gs.point[0]);
@ -689,7 +694,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
SK.constraint.ClearTags(); SK.constraint.ClearTags();
Constraint *c; Constraint *c;
for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) { for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
if(c->type != Constraint::POINTS_COINCIDENT) continue; if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
if(c->ptA.v == p->h.v || c->ptB.v == p->h.v) { if(c->ptA.v == p->h.v || c->ptB.v == p->h.v) {
c->tag = 1; c->tag = 1;
} }
@ -699,11 +704,11 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
break; break;
} }
case CMNU_SNAP_TO_GRID: case ContextCommand::SNAP_TO_GRID:
MenuEdit(MNU_SNAP_TO_GRID); MenuEdit(Command::SNAP_TO_GRID);
break; break;
case CMNU_REMOVE_SPLINE_PT: { case ContextCommand::REMOVE_SPLINE_PT: {
hRequest hr = gs.point[0].request(); hRequest hr = gs.point[0].request();
Request *r = SK.GetRequest(hr); Request *r = SK.GetRequest(hr);
@ -733,16 +738,16 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
break; break;
} }
case CMNU_ADD_SPLINE_PT: { case ContextCommand::ADD_SPLINE_PT: {
hRequest hr = gs.entity[0].request(); hRequest hr = gs.entity[0].request();
Request *r = SK.GetRequest(hr); Request *r = SK.GetRequest(hr);
int pointCount = r->extraPoints + ((r->type == Request::CUBIC_PERIODIC) ? 3 : 4); int pointCount = r->extraPoints + ((r->type == Request::Type::CUBIC_PERIODIC) ? 3 : 4);
if(pointCount < MAX_POINTS_IN_ENTITY) { if(pointCount < MAX_POINTS_IN_ENTITY) {
SS.UndoRemember(); SS.UndoRemember();
r->extraPoints++; r->extraPoints++;
SS.MarkGroupDirtyByEntity(gs.entity[0]); SS.MarkGroupDirtyByEntity(gs.entity[0]);
SS.GenerateAll(SolveSpaceUI::GENERATE_REGEN); SS.GenerateAll(SolveSpaceUI::Generate::REGEN);
Entity *e = SK.GetEntity(r->h.entity(0)); Entity *e = SK.GetEntity(r->h.entity(0));
for(int i = MAX_POINTS_IN_ENTITY; i > addAfterPoint + 1; i--) { for(int i = MAX_POINTS_IN_ENTITY; i > addAfterPoint + 1; i--) {
@ -763,7 +768,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
break; break;
} }
case CMNU_GROUP_INFO: { case ContextCommand::GROUP_INFO: {
hGroup hg; hGroup hg;
if(gs.entities == 1) { if(gs.entities == 1) {
hg = SK.GetEntity(gs.entity[0])->group; hg = SK.GetEntity(gs.entity[0])->group;
@ -776,14 +781,14 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
} }
ClearSelection(); ClearSelection();
SS.TW.GoToScreen(TextWindow::SCREEN_GROUP_INFO); SS.TW.GoToScreen(TextWindow::Screen::GROUP_INFO);
SS.TW.shown.group = hg; SS.TW.shown.group = hg;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
ForceTextWindowShown(); ForceTextWindowShown();
break; break;
} }
case CMNU_STYLE_INFO: { case ContextCommand::STYLE_INFO: {
hStyle hs; hStyle hs;
if(gs.entities == 1) { if(gs.entities == 1) {
hs = Style::ForEntity(gs.entity[0]); hs = Style::ForEntity(gs.entity[0]);
@ -796,31 +801,27 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
} }
ClearSelection(); ClearSelection();
SS.TW.GoToScreen(TextWindow::SCREEN_STYLE_INFO); SS.TW.GoToScreen(TextWindow::Screen::STYLE_INFO);
SS.TW.shown.style = hs; SS.TW.shown.style = hs;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
ForceTextWindowShown(); ForceTextWindowShown();
break; break;
} }
case CMNU_NEW_CUSTOM_STYLE: { case ContextCommand::NEW_CUSTOM_STYLE: {
uint32_t v = Style::CreateCustomStyle(); uint32_t v = Style::CreateCustomStyle();
Style::AssignSelectionToStyle(v); Style::AssignSelectionToStyle(v);
ForceTextWindowShown(); ForceTextWindowShown();
break; break;
} }
case CMNU_NO_STYLE: case ContextCommand::NO_STYLE:
Style::AssignSelectionToStyle(0); Style::AssignSelectionToStyle(0);
break; break;
default: default:
if(ret >= CMNU_FIRST_STYLE) { ssassert(ret >= ContextCommand::FIRST_STYLE, "Expected a style to be chosen");
Style::AssignSelectionToStyle(ret - CMNU_FIRST_STYLE); Style::AssignSelectionToStyle((uint32_t)ret - (uint32_t)ContextCommand::FIRST_STYLE);
} else {
// otherwise it was cancelled, so do nothing
contextMenuCancelTime = GetMilliseconds();
}
break; break;
} }
@ -828,16 +829,16 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
hRequest GraphicsWindow::AddRequest(int type) { hRequest GraphicsWindow::AddRequest(Request::Type type) {
return AddRequest(type, true); return AddRequest(type, true);
} }
hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) { hRequest GraphicsWindow::AddRequest(Request::Type type, bool rememberForUndo) {
if(rememberForUndo) SS.UndoRemember(); if(rememberForUndo) SS.UndoRemember();
Request r = {}; Request r = {};
r.group = activeGroup; r.group = activeGroup;
Group *g = SK.GetGroup(activeGroup); Group *g = SK.GetGroup(activeGroup);
if(g->type == Group::DRAWING_3D || g->type == Group::DRAWING_WORKPLANE) { if(g->type == Group::Type::DRAWING_3D || g->type == Group::Type::DRAWING_WORKPLANE) {
r.construction = false; r.construction = false;
} else { } else {
r.construction = true; r.construction = true;
@ -850,7 +851,7 @@ hRequest GraphicsWindow::AddRequest(int type, bool rememberForUndo) {
// place this request's entities where the mouse is can do so. But // place this request's entities where the mouse is can do so. But
// we mustn't try to solve until reasonable values have been supplied // we mustn't try to solve until reasonable values have been supplied
// for these new parameters, or else we'll get a numerical blowup. // for these new parameters, or else we'll get a numerical blowup.
SS.GenerateAll(SolveSpaceUI::GENERATE_REGEN); SS.GenerateAll(SolveSpaceUI::Generate::REGEN);
SS.MarkGroupDirty(r.group); SS.MarkGroupDirty(r.group);
return r.h; return r.h;
} }
@ -864,12 +865,12 @@ bool GraphicsWindow::ConstrainPointByHovered(hEntity pt) {
return true; return true;
} }
if(e->IsCircle()) { if(e->IsCircle()) {
Constraint::Constrain(Constraint::PT_ON_CIRCLE, Constraint::Constrain(Constraint::Type::PT_ON_CIRCLE,
pt, Entity::NO_ENTITY, e->h); pt, Entity::NO_ENTITY, e->h);
return true; return true;
} }
if(e->type == Entity::LINE_SEGMENT) { if(e->type == Entity::Type::LINE_SEGMENT) {
Constraint::Constrain(Constraint::PT_ON_LINE, Constraint::Constrain(Constraint::Type::PT_ON_LINE,
pt, Entity::NO_ENTITY, e->h); pt, Entity::NO_ENTITY, e->h);
return true; return true;
} }
@ -905,18 +906,18 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
hRequest hr; hRequest hr;
switch(pending.operation) { switch(pending.operation) {
case MNU_DATUM_POINT: case Command::DATUM_POINT:
hr = AddRequest(Request::DATUM_POINT); hr = AddRequest(Request::Type::DATUM_POINT);
SK.GetEntity(hr.entity(0))->PointForceTo(v); SK.GetEntity(hr.entity(0))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(0)); ConstrainPointByHovered(hr.entity(0));
ClearSuper(); ClearSuper();
break; break;
case MNU_LINE_SEGMENT: case Command::LINE_SEGMENT:
case MNU_CONSTR_SEGMENT: case Command::CONSTR_SEGMENT:
hr = AddRequest(Request::LINE_SEGMENT); hr = AddRequest(Request::Type::LINE_SEGMENT);
SK.GetRequest(hr)->construction = (pending.operation == MNU_CONSTR_SEGMENT); SK.GetRequest(hr)->construction = (pending.operation == (uint32_t)Command::CONSTR_SEGMENT);
SK.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
ConstrainPointByHovered(hr.entity(1)); ConstrainPointByHovered(hr.entity(1));
@ -929,7 +930,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
SK.GetEntity(pending.point)->PointForceTo(v); SK.GetEntity(pending.point)->PointForceTo(v);
break; break;
case MNU_RECTANGLE: { case Command::RECTANGLE: {
if(!SS.GW.LockedInWorkplane()) { if(!SS.GW.LockedInWorkplane()) {
Error("Can't draw rectangle in 3d; select a workplane first."); Error("Can't draw rectangle in 3d; select a workplane first.");
ClearSuper(); ClearSuper();
@ -939,7 +940,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
int i; int i;
SS.UndoRemember(); SS.UndoRemember();
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
lns[i] = AddRequest(Request::LINE_SEGMENT, false); lns[i] = AddRequest(Request::Type::LINE_SEGMENT, false);
} }
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
Constraint::ConstrainCoincident( Constraint::ConstrainCoincident(
@ -949,7 +950,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
} }
for(i = 0; i < 4; i++) { for(i = 0; i < 4; i++) {
Constraint::Constrain( Constraint::Constrain(
(i % 2) ? Constraint::HORIZONTAL : Constraint::VERTICAL, (i % 2) ? Constraint::Type::HORIZONTAL : Constraint::Type::VERTICAL,
Entity::NO_ENTITY, Entity::NO_ENTITY, Entity::NO_ENTITY, Entity::NO_ENTITY,
lns[i].entity(0)); lns[i].entity(0));
} }
@ -960,8 +961,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.description = "click to place other corner of rectangle"; pending.description = "click to place other corner of rectangle";
break; break;
} }
case MNU_CIRCLE: case Command::CIRCLE:
hr = AddRequest(Request::CIRCLE); hr = AddRequest(Request::Type::CIRCLE);
// Centered where we clicked // Centered where we clicked
SK.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
// Normal to the screen // Normal to the screen
@ -979,13 +980,13 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.description = "click to set radius"; pending.description = "click to set radius";
break; break;
case MNU_ARC: { case Command::ARC: {
if(!SS.GW.LockedInWorkplane()) { if(!SS.GW.LockedInWorkplane()) {
Error("Can't draw arc in 3d; select a workplane first."); Error("Can't draw arc in 3d; select a workplane first.");
ClearPending(); ClearPending();
break; break;
} }
hr = AddRequest(Request::ARC_OF_CIRCLE); hr = AddRequest(Request::Type::ARC_OF_CIRCLE);
// This fudge factor stops us from immediately failing to solve // This fudge factor stops us from immediately failing to solve
// because of the arc's implicit (equal radius) tangent. // because of the arc's implicit (equal radius) tangent.
Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale); Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale);
@ -1001,8 +1002,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.description = "click to place point"; pending.description = "click to place point";
break; break;
} }
case MNU_CUBIC: case Command::CUBIC:
hr = AddRequest(Request::CUBIC); hr = AddRequest(Request::Type::CUBIC);
SK.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(2))->PointForceTo(v); SK.GetEntity(hr.entity(2))->PointForceTo(v);
SK.GetEntity(hr.entity(3))->PointForceTo(v); SK.GetEntity(hr.entity(3))->PointForceTo(v);
@ -1016,14 +1017,14 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
pending.description = "click next point of cubic, or press Esc"; pending.description = "click next point of cubic, or press Esc";
break; break;
case MNU_WORKPLANE: case Command::WORKPLANE:
if(LockedInWorkplane()) { if(LockedInWorkplane()) {
Error("Sketching in a workplane already; sketch in 3d before " Error("Sketching in a workplane already; sketch in 3d before "
"creating new workplane."); "creating new workplane.");
ClearSuper(); ClearSuper();
break; break;
} }
hr = AddRequest(Request::WORKPLANE); hr = AddRequest(Request::Type::WORKPLANE);
SK.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
SK.GetEntity(hr.entity(32))->NormalForceTo( SK.GetEntity(hr.entity(32))->NormalForceTo(
Quaternion::From(SS.GW.projRight, SS.GW.projUp)); Quaternion::From(SS.GW.projRight, SS.GW.projUp));
@ -1032,13 +1033,13 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
ClearSuper(); ClearSuper();
break; break;
case MNU_TTF_TEXT: { case Command::TTF_TEXT: {
if(!SS.GW.LockedInWorkplane()) { if(!SS.GW.LockedInWorkplane()) {
Error("Can't draw text in 3d; select a workplane first."); Error("Can't draw text in 3d; select a workplane first.");
ClearSuper(); ClearSuper();
break; break;
} }
hr = AddRequest(Request::TTF_TEXT); hr = AddRequest(Request::Type::TTF_TEXT);
Request *r = SK.GetRequest(hr); Request *r = SK.GetRequest(hr);
r->str = "Abc"; r->str = "Abc";
r->font = "arial.ttf"; r->font = "arial.ttf";
@ -1052,12 +1053,12 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
break; break;
} }
case MNU_COMMENT: { case Command::COMMENT: {
ClearSuper(); ClearSuper();
Constraint c = {}; Constraint c = {};
c.group = SS.GW.activeGroup; c.group = SS.GW.activeGroup;
c.workplane = SS.GW.ActiveWorkplane(); c.workplane = SS.GW.ActiveWorkplane();
c.type = Constraint::COMMENT; c.type = Constraint::Type::COMMENT;
c.disp.offset = v; c.disp.offset = v;
c.comment = "NEW COMMENT -- DOUBLE-CLICK TO EDIT"; c.comment = "NEW COMMENT -- DOUBLE-CLICK TO EDIT";
Constraint::AddConstraint(&c); Constraint::AddConstraint(&c);
@ -1082,7 +1083,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
if(hover.entity.v == hr.entity(1).v && r->extraPoints >= 2) { if(hover.entity.v == hr.entity(1).v && r->extraPoints >= 2) {
// They want the endpoints coincident, which means a periodic // They want the endpoints coincident, which means a periodic
// spline instead. // spline instead.
r->type = Request::CUBIC_PERIODIC; r->type = Request::Type::CUBIC_PERIODIC;
// Remove the off-curve control points, which are no longer // Remove the off-curve control points, which are no longer
// needed here; so move [2,ep+1] down, skipping first pt. // needed here; so move [2,ep+1] down, skipping first pt.
int i; int i;
@ -1113,7 +1114,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
} }
(SK.GetRequest(hr)->extraPoints)++; (SK.GetRequest(hr)->extraPoints)++;
SS.GenerateAll(SolveSpaceUI::GENERATE_REGEN); SS.GenerateAll(SolveSpaceUI::Generate::REGEN);
int ep = r->extraPoints; int ep = r->extraPoints;
Vector last = SK.GetEntity(hr.entity(3+ep))->PointGetNum(); Vector last = SK.GetEntity(hr.entity(3+ep))->PointGetNum();
@ -1127,7 +1128,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
case DRAGGING_NEW_LINE_POINT: { case DRAGGING_NEW_LINE_POINT: {
// Constrain the line segment horizontal or vertical if close enough // Constrain the line segment horizontal or vertical if close enough
if(SS.GW.pending.suggestion != SUGGESTED_NONE) { if(SS.GW.pending.suggestion != Constraint::Type::UNKNOWN) {
Constraint::Constrain(SS.GW.pending.suggestion, Constraint::Constrain(SS.GW.pending.suggestion,
Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0)); Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0));
} }
@ -1155,7 +1156,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
} }
// Create a new line segment, so that we continue drawing. // Create a new line segment, so that we continue drawing.
hRequest hr = AddRequest(Request::LINE_SEGMENT); hRequest hr = AddRequest(Request::Type::LINE_SEGMENT);
SK.GetRequest(hr)->construction = SK.GetRequest(pending.request)->construction; SK.GetRequest(hr)->construction = SK.GetRequest(pending.request)->construction;
SK.GetEntity(hr.entity(1))->PointForceTo(v); SK.GetEntity(hr.entity(1))->PointForceTo(v);
// Displace the second point of the new line segment slightly, // Displace the second point of the new line segment slightly,
@ -1253,13 +1254,13 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
std::string editValue; std::string editValue;
int editMinWidthChar; int editMinWidthChar;
switch(c->type) { switch(c->type) {
case Constraint::COMMENT: case Constraint::Type::COMMENT:
editValue = c->comment; editValue = c->comment;
editMinWidthChar = 30; editMinWidthChar = 30;
break; break;
case Constraint::ANGLE: case Constraint::Type::ANGLE:
case Constraint::LENGTH_RATIO: case Constraint::Type::LENGTH_RATIO:
editValue = ssprintf("%.3f", c->valA); editValue = ssprintf("%.3f", c->valA);
editMinWidthChar = 5; editMinWidthChar = 5;
break; break;
@ -1268,7 +1269,7 @@ void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) {
double v = fabs(c->valA); double v = fabs(c->valA);
// If displayed as radius, also edit as radius. // If displayed as radius, also edit as radius.
if(c->type == Constraint::DIAMETER && c->other) if(c->type == Constraint::Type::DIAMETER && c->other)
v /= 2; v /= 2;
std::string def = SS.MmToString(v); std::string def = SS.MmToString(v);
@ -1303,7 +1304,7 @@ void GraphicsWindow::EditControlDone(const char *s) {
HideGraphicsEditControl(); HideGraphicsEditControl();
Constraint *c = SK.GetConstraint(constraintBeingEdited); Constraint *c = SK.GetConstraint(constraintBeingEdited);
if(c->type == Constraint::COMMENT) { if(c->type == Constraint::Type::COMMENT) {
SS.UndoRemember(); SS.UndoRemember();
c->comment = s; c->comment = s;
return; return;
@ -1314,11 +1315,11 @@ void GraphicsWindow::EditControlDone(const char *s) {
SS.UndoRemember(); SS.UndoRemember();
switch(c->type) { switch(c->type) {
case Constraint::PROJ_PT_DISTANCE: case Constraint::Type::PROJ_PT_DISTANCE:
case Constraint::PT_LINE_DISTANCE: case Constraint::Type::PT_LINE_DISTANCE:
case Constraint::PT_FACE_DISTANCE: case Constraint::Type::PT_FACE_DISTANCE:
case Constraint::PT_PLANE_DISTANCE: case Constraint::Type::PT_PLANE_DISTANCE:
case Constraint::LENGTH_DIFFERENCE: { case Constraint::Type::LENGTH_DIFFERENCE: {
// The sign is not displayed to the user, but this is a signed // The sign is not displayed to the user, but this is a signed
// distance internally. To flip the sign, the user enters a // distance internally. To flip the sign, the user enters a
// negative distance. // negative distance.
@ -1330,14 +1331,14 @@ void GraphicsWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case Constraint::ANGLE: case Constraint::Type::ANGLE:
case Constraint::LENGTH_RATIO: case Constraint::Type::LENGTH_RATIO:
// These don't get the units conversion for distance, and // These don't get the units conversion for distance, and
// they're always positive // they're always positive
c->valA = fabs(e->Eval()); c->valA = fabs(e->Eval());
break; break;
case Constraint::DIAMETER: case Constraint::Type::DIAMETER:
c->valA = fabs(SS.ExprToMm(e)); c->valA = fabs(SS.ExprToMm(e));
// If displayed and edited as radius, convert back // If displayed and edited as radius, convert back
@ -1359,7 +1360,7 @@ void GraphicsWindow::EditControlDone(const char *s) {
bool GraphicsWindow::KeyDown(int c) { bool GraphicsWindow::KeyDown(int c) {
if(c == '\b') { if(c == '\b') {
// Treat backspace identically to escape. // Treat backspace identically to escape.
MenuEdit(MNU_UNSELECT_ALL); MenuEdit(Command::UNSELECT_ALL);
return true; return true;
} }
@ -1385,7 +1386,7 @@ 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(SS.TW.shown.screen == TextWindow::Screen::EDIT_VIEW) {
if(havePainted) { if(havePainted) {
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
@ -1399,8 +1400,8 @@ void GraphicsWindow::MouseLeave() {
// currently a context menu shown. // currently a context menu shown.
if(!context.active) { if(!context.active) {
hover.Clear(); hover.Clear();
toolbarTooltipped = 0; toolbarTooltipped = Command::NONE;
toolbarHovered = 0; toolbarHovered = Command::NONE;
PaintGraphics(); PaintGraphics();
} }
SS.extraLine.draw = false; SS.extraLine.draw = false;
@ -1427,7 +1428,7 @@ void GraphicsWindow::SpaceNavigatorMoved(double tx, double ty, double tz,
if(gs.points == 1 && gs.n == 1) e = SK.GetEntity(gs.point [0]); if(gs.points == 1 && gs.n == 1) e = SK.GetEntity(gs.point [0]);
if(gs.entities == 1 && gs.n == 1) e = SK.GetEntity(gs.entity[0]); if(gs.entities == 1 && gs.n == 1) e = SK.GetEntity(gs.entity[0]);
if(e) g = SK.GetGroup(e->group); if(e) g = SK.GetGroup(e->group);
if(g && g->type == Group::LINKED && !shiftDown) { if(g && g->type == Group::Type::LINKED && !shiftDown) {
// Apply the transformation to a linked part. Gain down the Z // Apply the transformation to a linked part. Gain down the Z
// axis, since it's hard to see what you're doing on that one since // axis, since it's hard to see what you're doing on that one since
// it's normal to the screen. // it's normal to the screen.

View File

@ -536,7 +536,7 @@ bool GraphicsEditControlIsVisible(void) {
/* Context menus */ /* Context menus */
static int contextMenuChoice; static SolveSpace::ContextCommand contextMenuChoice;
@interface ContextMenuResponder : NSObject @interface ContextMenuResponder : NSObject
+ (void)handleClick:(id)sender; + (void)handleClick:(id)sender;
@ -544,25 +544,25 @@ static int contextMenuChoice;
@implementation ContextMenuResponder @implementation ContextMenuResponder
+ (void)handleClick:(id)sender { + (void)handleClick:(id)sender {
contextMenuChoice = [sender tag]; contextMenuChoice = (SolveSpace::ContextCommand)[sender tag];
} }
@end @end
namespace SolveSpace { namespace SolveSpace {
NSMenu *contextMenu, *contextSubmenu; NSMenu *contextMenu, *contextSubmenu;
void AddContextMenuItem(const char *label, int id_) { void AddContextMenuItem(const char *label, ContextCommand cmd) {
NSMenuItem *menuItem; NSMenuItem *menuItem;
if(label) { if(label) {
menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:label] menuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithUTF8String:label]
action:@selector(handleClick:) keyEquivalent:@""]; action:@selector(handleClick:) keyEquivalent:@""];
[menuItem setTarget:[ContextMenuResponder class]]; [menuItem setTarget:[ContextMenuResponder class]];
[menuItem setTag:id_]; [menuItem setTag:(NSInteger)cmd];
} else { } else {
menuItem = [NSMenuItem separatorItem]; menuItem = [NSMenuItem separatorItem];
} }
if(id_ == CONTEXT_SUBMENU) { if(cmd == SolveSpace::ContextCommand::SUBMENU) {
[menuItem setSubmenu:contextSubmenu]; [menuItem setSubmenu:contextSubmenu];
contextSubmenu = nil; contextSubmenu = nil;
} }
@ -585,9 +585,9 @@ void CreateContextSubmenu(void) {
contextSubmenu = [[NSMenu alloc] initWithTitle:@""]; contextSubmenu = [[NSMenu alloc] initWithTitle:@""];
} }
int ShowContextMenu(void) { ContextCommand ShowContextMenu(void) {
if(!contextMenu) if(!contextMenu)
return -1; return ContextCommand::CANCELLED;
[NSMenu popUpContextMenu:contextMenu [NSMenu popUpContextMenu:contextMenu
withEvent:[GWView lastContextMenuEvent] forView:GWView]; withEvent:[GWView lastContextMenuEvent] forView:GWView];
@ -615,16 +615,19 @@ int ShowContextMenu(void) {
} }
+ (void)handleRecent:(id)sender { + (void)handleRecent:(id)sender {
int id_ = [sender tag]; uint32_t cmd = [sender tag];
if(id_ >= RECENT_OPEN && id_ < (RECENT_OPEN + MAX_RECENT)) if(cmd >= (uint32_t)SolveSpace::Command::RECENT_OPEN &&
SolveSpace::SolveSpaceUI::MenuFile(id_); cmd < ((uint32_t)SolveSpace::Command::RECENT_OPEN + SolveSpace::MAX_RECENT)) {
else if(id_ >= RECENT_LINK && id_ < (RECENT_LINK + MAX_RECENT)) SolveSpace::SolveSpaceUI::MenuFile((SolveSpace::Command)cmd);
SolveSpace::Group::MenuGroup(id_); } else if(cmd >= (uint32_t)SolveSpace::Command::RECENT_LINK &&
cmd < ((uint32_t)SolveSpace::Command::RECENT_LINK + SolveSpace::MAX_RECENT)) {
SolveSpace::Group::MenuGroup((SolveSpace::Command)cmd);
}
} }
@end @end
namespace SolveSpace { namespace SolveSpace {
std::map<int, NSMenuItem*> mainMenuItems; std::map<uint32_t, NSMenuItem*> mainMenuItems;
void InitMainMenu(NSMenu *mainMenu) { void InitMainMenu(NSMenu *mainMenu) {
NSMenuItem *menuItem = NULL; NSMenuItem *menuItem = NULL;
@ -676,26 +679,26 @@ void InitMainMenu(NSMenu *mainMenu) {
[levels[entry->level] addItem:[NSMenuItem separatorItem]]; [levels[entry->level] addItem:[NSMenuItem separatorItem]];
} }
mainMenuItems[entry->id] = menuItem; mainMenuItems[(uint32_t)entry->id] = menuItem;
++entry; ++entry;
} }
} }
void EnableMenuById(int id_, bool enabled) { void EnableMenuByCmd(SolveSpace::Command cmd, bool enabled) {
[mainMenuItems[id_] setEnabled:enabled]; [mainMenuItems[(uint32_t)cmd] setEnabled:enabled];
} }
void CheckMenuById(int id_, bool checked) { void CheckMenuByCmd(SolveSpace::Command cmd, bool checked) {
[mainMenuItems[id_] setState:(checked ? NSOnState : NSOffState)]; [mainMenuItems[(uint32_t)cmd] setState:(checked ? NSOnState : NSOffState)];
} }
void RadioMenuById(int id_, bool selected) { void RadioMenuByCmd(SolveSpace::Command cmd, bool selected) {
CheckMenuById(id_, selected); CheckMenuByCmd(cmd, selected);
} }
static void RefreshRecentMenu(int id_, int base) { static void RefreshRecentMenu(SolveSpace::Command cmd, SolveSpace::Command base) {
NSMenuItem *recent = mainMenuItems[id_]; NSMenuItem *recent = mainMenuItems[(uint32_t)cmd];
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""]; NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
[recent setSubmenu:menu]; [recent setSubmenu:menu];
@ -705,7 +708,7 @@ static void RefreshRecentMenu(int id_, int base) {
[placeholder setEnabled:NO]; [placeholder setEnabled:NO];
[menu addItem:placeholder]; [menu addItem:placeholder];
} else { } else {
for(int i = 0; i < MAX_RECENT; i++) { for(size_t i = 0; i < MAX_RECENT; i++) {
if(std::string(RecentFile[i]).empty()) if(std::string(RecentFile[i]).empty())
break; break;
@ -713,7 +716,7 @@ static void RefreshRecentMenu(int id_, int base) {
initWithTitle:[[NSString stringWithUTF8String:RecentFile[i].c_str()] initWithTitle:[[NSString stringWithUTF8String:RecentFile[i].c_str()]
stringByAbbreviatingWithTildeInPath] stringByAbbreviatingWithTildeInPath]
action:nil keyEquivalent:@""]; action:nil keyEquivalent:@""];
[item setTag:(base + i)]; [item setTag:((uint32_t)base + i)];
[item setAction:@selector(handleRecent:)]; [item setAction:@selector(handleRecent:)];
[item setTarget:[MainMenuResponder class]]; [item setTarget:[MainMenuResponder class]];
[menu addItem:item]; [menu addItem:item];
@ -722,8 +725,8 @@ static void RefreshRecentMenu(int id_, int base) {
} }
void RefreshRecentMenus(void) { void RefreshRecentMenus(void) {
RefreshRecentMenu(GraphicsWindow::MNU_OPEN_RECENT, RECENT_OPEN); RefreshRecentMenu(Command::OPEN_RECENT, Command::RECENT_OPEN);
RefreshRecentMenu(GraphicsWindow::MNU_GROUP_RECENT, RECENT_LINK); RefreshRecentMenu(Command::GROUP_RECENT, Command::RECENT_LINK);
} }
void ToggleMenuBar(void) { void ToggleMenuBar(void) {
@ -1001,7 +1004,7 @@ SolveSpace::DialogChoice SolveSpace::LocateImportedFileYesNoCancel(
@implementation TextWindowDelegate @implementation TextWindowDelegate
- (BOOL)windowShouldClose:(id)sender { - (BOOL)windowShouldClose:(id)sender {
SolveSpace::GraphicsWindow::MenuView(SolveSpace::GraphicsWindow::MNU_SHOW_TEXT_WND); SolveSpace::GraphicsWindow::MenuView(SolveSpace::Command::SHOW_TEXT_WND);
return NO; return NO;
} }
@ -1186,7 +1189,7 @@ const void *SolveSpace::LoadResource(const std::string &name, size_t *size) {
} }
- (IBAction)preferences:(id)sender { - (IBAction)preferences:(id)sender {
SolveSpace::SS.TW.GoToScreen(SolveSpace::TextWindow::SCREEN_CONFIGURATION); SolveSpace::SS.TW.GoToScreen(SolveSpace::TextWindow::Screen::CONFIGURATION);
SolveSpace::SS.ScheduleShowTW(); SolveSpace::SS.ScheduleShowTW();
} }
@end @end

View File

@ -703,7 +703,7 @@ protected:
if(chr == '\t') { if(chr == '\t') {
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=123994. // Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=123994.
GraphicsWindow::MenuView(GraphicsWindow::MNU_SHOW_TEXT_WND); GraphicsWindow::MenuView(Command::SHOW_TEXT_WND);
return true; return true;
} }
@ -794,10 +794,10 @@ bool MenuBarIsVisible(void) {
class ContextMenuItem : public Gtk::MenuItem { class ContextMenuItem : public Gtk::MenuItem {
public: public:
static int choice; static ContextCommand choice;
ContextMenuItem(const Glib::ustring &label, int id, bool mnemonic=false) : ContextMenuItem(const Glib::ustring &label, ContextCommand cmd, bool mnemonic=false) :
Gtk::MenuItem(label, mnemonic), _id(id) { Gtk::MenuItem(label, mnemonic), _cmd(cmd) {
} }
protected: protected:
@ -807,7 +807,7 @@ protected:
if(has_submenu()) if(has_submenu())
return; return;
choice = _id; choice = _cmd;
} }
/* Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=695488. /* Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=695488.
@ -826,21 +826,21 @@ protected:
} }
private: private:
int _id; ContextCommand _cmd;
}; };
int ContextMenuItem::choice = 0; ContextCommand ContextMenuItem::choice = ContextCommand::CANCELLED;
static Gtk::Menu *context_menu = NULL, *context_submenu = NULL; static Gtk::Menu *context_menu = NULL, *context_submenu = NULL;
void AddContextMenuItem(const char *label, int id) { void AddContextMenuItem(const char *label, ContextCommand cmd) {
Gtk::MenuItem *menu_item; Gtk::MenuItem *menu_item;
if(label) if(label)
menu_item = new ContextMenuItem(label, id); menu_item = new ContextMenuItem(label, cmd);
else else
menu_item = new Gtk::SeparatorMenuItem(); menu_item = new Gtk::SeparatorMenuItem();
if(id == CONTEXT_SUBMENU) { if(cmd == ContextCommand::SUBMENU) {
menu_item->set_submenu(*context_submenu); menu_item->set_submenu(*context_submenu);
context_submenu = NULL; context_submenu = NULL;
} }
@ -861,15 +861,15 @@ void CreateContextSubmenu(void) {
context_submenu = new Gtk::Menu; context_submenu = new Gtk::Menu;
} }
int ShowContextMenu(void) { ContextCommand ShowContextMenu(void) {
if(!context_menu) if(!context_menu)
return -1; return ContextCommand::CANCELLED;
Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create(); Glib::RefPtr<Glib::MainLoop> loop = Glib::MainLoop::create();
context_menu->signal_deactivate(). context_menu->signal_deactivate().
connect(sigc::mem_fun(loop.operator->(), &Glib::MainLoop::quit)); connect(sigc::mem_fun(loop.operator->(), &Glib::MainLoop::quit));
ContextMenuItem::choice = -1; ContextMenuItem::choice = ContextCommand::CANCELLED;
context_menu->show_all(); context_menu->show_all();
context_menu->popup(3, GDK_CURRENT_TIME); context_menu->popup(3, GDK_CURRENT_TIME);
@ -952,7 +952,7 @@ private:
bool _synthetic; bool _synthetic;
}; };
static std::map<int, Gtk::MenuItem *> main_menu_items; static std::map<uint32_t, Gtk::MenuItem *> main_menu_items;
static void InitMainMenu(Gtk::MenuShell *menu_shell) { static void InitMainMenu(Gtk::MenuShell *menu_shell) {
Gtk::MenuItem *menu_item = NULL; Gtk::MenuItem *menu_item = NULL;
@ -975,15 +975,15 @@ static void InitMainMenu(Gtk::MenuShell *menu_shell) {
if(entry->label) { if(entry->label) {
switch(entry->kind) { switch(entry->kind) {
case GraphicsWindow::MENU_ITEM_NORMAL: case GraphicsWindow::MenuKind::NORMAL:
menu_item = new MainMenuItem<Gtk::MenuItem>(*entry); menu_item = new MainMenuItem<Gtk::MenuItem>(*entry);
break; break;
case GraphicsWindow::MENU_ITEM_CHECK: case GraphicsWindow::MenuKind::CHECK:
menu_item = new MainMenuItem<Gtk::CheckMenuItem>(*entry); menu_item = new MainMenuItem<Gtk::CheckMenuItem>(*entry);
break; break;
case GraphicsWindow::MENU_ITEM_RADIO: case GraphicsWindow::MenuKind::RADIO:
MainMenuItem<Gtk::CheckMenuItem> *radio_item = MainMenuItem<Gtk::CheckMenuItem> *radio_item =
new MainMenuItem<Gtk::CheckMenuItem>(*entry); new MainMenuItem<Gtk::CheckMenuItem>(*entry);
radio_item->set_draw_as_radio(true); radio_item->set_draw_as_radio(true);
@ -996,44 +996,47 @@ static void InitMainMenu(Gtk::MenuShell *menu_shell) {
levels[entry->level]->append(*menu_item); levels[entry->level]->append(*menu_item);
main_menu_items[entry->id] = menu_item; main_menu_items[(uint32_t)entry->id] = menu_item;
++entry; ++entry;
} }
} }
void EnableMenuById(int id, bool enabled) { void EnableMenuByCmd(Command cmd, bool enabled) {
main_menu_items[id]->set_sensitive(enabled); main_menu_items[(uint32_t)cmd]->set_sensitive(enabled);
} }
void CheckMenuById(int id, bool checked) { void CheckMenuByCmd(Command cmd, bool checked) {
((MainMenuItem<Gtk::CheckMenuItem>*)main_menu_items[id])->set_active(checked); ((MainMenuItem<Gtk::CheckMenuItem>*)main_menu_items[(uint32_t)cmd])->set_active(checked);
} }
void RadioMenuById(int id, bool selected) { void RadioMenuByCmd(Command cmd, bool selected) {
SolveSpace::CheckMenuById(id, selected); SolveSpace::CheckMenuByCmd(cmd, selected);
} }
class RecentMenuItem : public Gtk::MenuItem { class RecentMenuItem : public Gtk::MenuItem {
public: public:
RecentMenuItem(const Glib::ustring& label, int id) : RecentMenuItem(const Glib::ustring& label, uint32_t cmd) :
MenuItem(label), _id(id) { MenuItem(label), _cmd(cmd) {
} }
protected: protected:
void on_activate() override { void on_activate() override {
if(_id >= RECENT_OPEN && _id < (RECENT_OPEN + MAX_RECENT)) if(_cmd >= (uint32_t)Command::RECENT_OPEN &&
SolveSpaceUI::MenuFile(_id); _cmd < ((uint32_t)Command::RECENT_OPEN + MAX_RECENT)) {
else if(_id >= RECENT_LINK && _id < (RECENT_LINK + MAX_RECENT)) SolveSpaceUI::MenuFile((Command)_cmd);
Group::MenuGroup(_id); } else if(_cmd >= (uint32_t)Command::RECENT_LINK &&
_cmd < ((uint32_t)Command::RECENT_LINK + MAX_RECENT)) {
Group::MenuGroup((Command)_cmd);
}
} }
private: private:
int _id; uint32_t _cmd;
}; };
static void RefreshRecentMenu(int id, int base) { static void RefreshRecentMenu(Command cmd, Command base) {
Gtk::MenuItem *recent = static_cast<Gtk::MenuItem*>(main_menu_items[id]); Gtk::MenuItem *recent = static_cast<Gtk::MenuItem*>(main_menu_items[(uint32_t)cmd]);
recent->unset_submenu(); recent->unset_submenu();
Gtk::Menu *menu = new Gtk::Menu; Gtk::Menu *menu = new Gtk::Menu;
@ -1048,7 +1051,7 @@ static void RefreshRecentMenu(int id, int base) {
if(std::string(RecentFile[i]).empty()) if(std::string(RecentFile[i]).empty())
break; break;
RecentMenuItem *item = new RecentMenuItem(RecentFile[i], base + i); RecentMenuItem *item = new RecentMenuItem(RecentFile[i], (uint32_t)base + i);
menu->append(*item); menu->append(*item);
} }
} }
@ -1057,8 +1060,8 @@ static void RefreshRecentMenu(int id, int base) {
} }
void RefreshRecentMenus(void) { void RefreshRecentMenus(void) {
RefreshRecentMenu(GraphicsWindow::MNU_OPEN_RECENT, RECENT_OPEN); RefreshRecentMenu(Command::OPEN_RECENT, Command::RECENT_OPEN);
RefreshRecentMenu(GraphicsWindow::MNU_GROUP_RECENT, RECENT_LINK); RefreshRecentMenu(Command::GROUP_RECENT, Command::RECENT_LINK);
} }
/* Save/load */ /* Save/load */
@ -1386,7 +1389,7 @@ protected:
bool on_delete_event(GdkEventAny *) override { bool on_delete_event(GdkEventAny *) override {
/* trigger the action and ignore the request */ /* trigger the action and ignore the request */
GraphicsWindow::MenuView(GraphicsWindow::MNU_SHOW_TEXT_WND); GraphicsWindow::MenuView(Command::SHOW_TEXT_WND);
return false; return false;
} }

View File

@ -185,20 +185,20 @@ void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error)
DestroyWindow(MessageWnd); DestroyWindow(MessageWnd);
} }
void SolveSpace::AddContextMenuItem(const char *label, int id) void SolveSpace::AddContextMenuItem(const char *label, ContextCommand cmd)
{ {
if(!ContextMenu) ContextMenu = CreatePopupMenu(); if(!ContextMenu) ContextMenu = CreatePopupMenu();
if(id == CONTEXT_SUBMENU) { if(cmd == ContextCommand::SUBMENU) {
AppendMenuW(ContextMenu, MF_STRING | MF_POPUP, AppendMenuW(ContextMenu, MF_STRING | MF_POPUP,
(UINT_PTR)ContextSubmenu, Widen(label).c_str()); (UINT_PTR)ContextSubmenu, Widen(label).c_str());
ContextSubmenu = NULL; ContextSubmenu = NULL;
} else { } else {
HMENU m = ContextSubmenu ? ContextSubmenu : ContextMenu; HMENU m = ContextSubmenu ? ContextSubmenu : ContextMenu;
if(id == CONTEXT_SEPARATOR) { if(cmd == ContextCommand::SEPARATOR) {
AppendMenuW(m, MF_SEPARATOR, 0, L""); AppendMenuW(m, MF_SEPARATOR, 0, L"");
} else { } else {
AppendMenuW(m, MF_STRING, id, Widen(label).c_str()); AppendMenuW(m, MF_STRING, (uint32_t)cmd, Widen(label).c_str());
} }
} }
} }
@ -208,7 +208,7 @@ void SolveSpace::CreateContextSubmenu()
ContextSubmenu = CreatePopupMenu(); ContextSubmenu = CreatePopupMenu();
} }
int SolveSpace::ShowContextMenu() ContextCommand SolveSpace::ShowContextMenu()
{ {
POINT p; POINT p;
GetCursorPos(&p); GetCursorPos(&p);
@ -218,7 +218,7 @@ int SolveSpace::ShowContextMenu()
DestroyMenu(ContextMenu); DestroyMenu(ContextMenu);
ContextMenu = NULL; ContextMenu = NULL;
return r; return (ContextCommand)r;
} }
void CALLBACK TimerCallback(HWND hwnd, UINT msg, UINT_PTR id, DWORD time) void CALLBACK TimerCallback(HWND hwnd, UINT msg, UINT_PTR id, DWORD time)
@ -521,7 +521,7 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_CLOSE: case WM_CLOSE:
case WM_DESTROY: case WM_DESTROY:
SolveSpaceUI::MenuFile(GraphicsWindow::MNU_EXIT); SolveSpaceUI::MenuFile(Command::EXIT);
break; break;
case WM_PAINT: { case WM_PAINT: {
@ -699,7 +699,7 @@ static bool ProcessKeyDown(WPARAM wParam)
for(int i = 0; SS.GW.menu[i].level >= 0; i++) { for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
if(c == SS.GW.menu[i].accel) { if(c == SS.GW.menu[i].accel) {
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id); (SS.GW.menu[i].fn)((Command)SS.GW.menu[i].id);
break; break;
} }
} }
@ -937,19 +937,21 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_COMMAND: { case WM_COMMAND: {
if(HIWORD(wParam) == 0) { if(HIWORD(wParam) == 0) {
int id = LOWORD(wParam); Command id = (Command)LOWORD(wParam);
if((id >= RECENT_OPEN && id < (RECENT_OPEN + MAX_RECENT))) { if(((uint32_t)id >= (uint32_t)Command::RECENT_OPEN &&
(uint32_t)id < ((uint32_t)Command::RECENT_OPEN + MAX_RECENT))) {
SolveSpaceUI::MenuFile(id); SolveSpaceUI::MenuFile(id);
break; break;
} }
if((id >= RECENT_LINK && id < (RECENT_LINK + MAX_RECENT))) { if(((uint32_t)id >= (uint32_t)Command::RECENT_LINK &&
(uint32_t)id < ((uint32_t)Command::RECENT_LINK + MAX_RECENT))) {
Group::MenuGroup(id); Group::MenuGroup(id);
break; break;
} }
int i; int i;
for(i = 0; SS.GW.menu[i].level >= 0; i++) { for(i = 0; SS.GW.menu[i].level >= 0; i++) {
if(id == SS.GW.menu[i].id) { if(id == SS.GW.menu[i].id) {
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id); (SS.GW.menu[i].fn)((Command)id);
break; break;
} }
} }
@ -960,7 +962,7 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_CLOSE: case WM_CLOSE:
case WM_DESTROY: case WM_DESTROY:
SolveSpaceUI::MenuFile(GraphicsWindow::MNU_EXIT); SolveSpaceUI::MenuFile(Command::EXIT);
return 1; return 1;
default: default:
@ -1142,7 +1144,7 @@ std::vector<std::string> SolveSpace::GetFontFiles() {
return fonts; return fonts;
} }
static void MenuById(int id, bool yes, bool check) static void MenuByCmd(Command id, bool yes, bool check)
{ {
int i; int i;
int subMenu = -1; int subMenu = -1;
@ -1155,10 +1157,10 @@ static void MenuById(int id, bool yes, bool check)
"Submenu out of range"); "Submenu out of range");
if(check) { if(check) {
CheckMenuItem(SubMenus[subMenu], id, CheckMenuItem(SubMenus[subMenu], (uint32_t)id,
yes ? MF_CHECKED : MF_UNCHECKED); yes ? MF_CHECKED : MF_UNCHECKED);
} else { } else {
EnableMenuItem(SubMenus[subMenu], id, EnableMenuItem(SubMenus[subMenu], (uint32_t)id,
yes ? MF_ENABLED : MF_GRAYED); yes ? MF_ENABLED : MF_GRAYED);
} }
return; return;
@ -1166,27 +1168,27 @@ static void MenuById(int id, bool yes, bool check)
} }
ssassert(false, "Cannot find submenu"); ssassert(false, "Cannot find submenu");
} }
void SolveSpace::CheckMenuById(int id, bool checked) void SolveSpace::CheckMenuByCmd(Command cmd, bool checked)
{ {
MenuById(id, checked, true); MenuByCmd(cmd, checked, true);
} }
void SolveSpace::RadioMenuById(int id, bool selected) void SolveSpace::RadioMenuByCmd(Command cmd, bool selected)
{ {
// Windows does not natively support radio-button menu items // Windows does not natively support radio-button menu items
MenuById(id, selected, true); MenuByCmd(cmd, selected, true);
} }
void SolveSpace::EnableMenuById(int id, bool enabled) void SolveSpace::EnableMenuByCmd(Command cmd, bool enabled)
{ {
MenuById(id, enabled, false); MenuByCmd(cmd, enabled, false);
} }
static void DoRecent(HMENU m, int base) static void DoRecent(HMENU m, Command base)
{ {
while(DeleteMenu(m, 0, MF_BYPOSITION)) while(DeleteMenu(m, 0, MF_BYPOSITION))
; ;
int i, c = 0; int c = 0;
for(i = 0; i < MAX_RECENT; i++) { for(size_t i = 0; i < MAX_RECENT; i++) {
if(!RecentFile[i].empty()) { if(!RecentFile[i].empty()) {
AppendMenuW(m, MF_STRING, base + i, Widen(RecentFile[i]).c_str()); AppendMenuW(m, MF_STRING, (uint32_t)base + i, Widen(RecentFile[i]).c_str());
c++; c++;
} }
} }
@ -1194,8 +1196,8 @@ static void DoRecent(HMENU m, int base)
} }
void SolveSpace::RefreshRecentMenus() void SolveSpace::RefreshRecentMenus()
{ {
DoRecent(RecentOpenMenu, RECENT_OPEN); DoRecent(RecentOpenMenu, Command::RECENT_OPEN);
DoRecent(RecentImportMenu, RECENT_LINK); DoRecent(RecentImportMenu, Command::RECENT_LINK);
} }
HMENU CreateGraphicsWindowMenus() HMENU CreateGraphicsWindowMenus()
@ -1221,18 +1223,18 @@ HMENU CreateGraphicsWindowMenus()
SubMenus[subMenu] = m; SubMenus[subMenu] = m;
subMenu++; subMenu++;
} else if(SS.GW.menu[i].level == 1) { } else if(SS.GW.menu[i].level == 1) {
if(SS.GW.menu[i].id == GraphicsWindow::MNU_OPEN_RECENT) { if(SS.GW.menu[i].id == Command::OPEN_RECENT) {
RecentOpenMenu = CreateMenu(); RecentOpenMenu = CreateMenu();
AppendMenuW(m, MF_STRING | MF_POPUP, AppendMenuW(m, MF_STRING | MF_POPUP,
(UINT_PTR)RecentOpenMenu, Widen(label).c_str()); (UINT_PTR)RecentOpenMenu, Widen(label).c_str());
} else if(SS.GW.menu[i].id == GraphicsWindow::MNU_GROUP_RECENT) { } else if(SS.GW.menu[i].id == Command::GROUP_RECENT) {
RecentImportMenu = CreateMenu(); RecentImportMenu = CreateMenu();
AppendMenuW(m, MF_STRING | MF_POPUP, AppendMenuW(m, MF_STRING | MF_POPUP,
(UINT_PTR)RecentImportMenu, Widen(label).c_str()); (UINT_PTR)RecentImportMenu, Widen(label).c_str());
} else if(SS.GW.menu[i].label) { } else if(SS.GW.menu[i].label) {
AppendMenuW(m, MF_STRING, SS.GW.menu[i].id, Widen(label).c_str()); AppendMenuW(m, MF_STRING, (uint32_t)SS.GW.menu[i].id, Widen(label).c_str());
} else { } else {
AppendMenuW(m, MF_SEPARATOR, SS.GW.menu[i].id, L""); AppendMenuW(m, MF_SEPARATOR, (uint32_t)SS.GW.menu[i].id, L"");
} }
} else ssassert(false, "Submenus nested too deeply"); } else ssassert(false, "Submenus nested too deeply");
} }

View File

@ -15,6 +15,26 @@ class SMesh;
class SBsp3; class SBsp3;
class SOutlineList; class SOutlineList;
enum class EarType : uint32_t {
UNKNOWN = 0,
NOT_EAR = 1,
EAR = 2
};
enum class BspClass : uint32_t {
POS = 100,
NEG = 101,
COPLANAR = 200
};
enum class EdgeKind : uint32_t {
NAKED_OR_SELF_INTER = 100,
SELF_INTER = 200,
TURNING = 300,
EMPHASIZED = 400,
SHARP = 500,
};
class SEdge { class SEdge {
public: public:
int tag; int tag;
@ -75,12 +95,7 @@ class SPoint {
public: public:
int tag; int tag;
enum { EarType ear;
UNKNOWN = 0,
NOT_EAR = 1,
EAR = 2
};
int ear;
Vector p; Vector p;
Vector auxv; Vector auxv;
@ -177,8 +192,7 @@ public:
SBsp2 *more; SBsp2 *more;
enum { POS = 100, NEG = 101, COPLANAR = 200 }; void InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3);
void InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3);
void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3); void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3);
Vector IntersectionWith(Vector a, Vector b) const; Vector IntersectionWith(Vector a, Vector b) const;
void InsertEdge(SEdge *nedge, Vector nnp, Vector out); void InsertEdge(SEdge *nedge, Vector nnp, Vector out);
@ -207,12 +221,11 @@ public:
Vector IntersectionWith(Vector a, Vector b) const; Vector IntersectionWith(Vector a, Vector b) const;
enum { POS = 100, NEG = 101, COPLANAR = 200 }; void InsertHow(BspClass how, STriangle *str, SMesh *instead);
void InsertHow(int how, STriangle *str, SMesh *instead);
void Insert(STriangle *str, SMesh *instead); void Insert(STriangle *str, SMesh *instead);
static SBsp3 *InsertOrCreate(SBsp3 *where, STriangle *str, SMesh *instead); static SBsp3 *InsertOrCreate(SBsp3 *where, STriangle *str, SMesh *instead);
void InsertConvexHow(int how, STriMeta meta, Vector *vertex, int n, void InsertConvexHow(BspClass how, STriMeta meta, Vector *vertex, int n,
SMesh *instead); SMesh *instead);
SBsp3 *InsertConvex(STriMeta meta, Vector *vertex, int n, SMesh *instead); SBsp3 *InsertConvex(STriMeta meta, Vector *vertex, int n, SMesh *instead);
@ -252,7 +265,7 @@ public:
void MakeFromAssemblyOf(SMesh *a, SMesh *b); void MakeFromAssemblyOf(SMesh *a, SMesh *b);
void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d); void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d);
void MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, int type); void MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, EdgeKind type);
bool IsEmpty() const; bool IsEmpty() const;
void RemapFaces(Group *g, int remap); void RemapFaces(Group *g, int remap);
@ -317,14 +330,7 @@ public:
void ClearTags() const; void ClearTags() const;
void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info) const; void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info) const;
enum { void MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter,
NAKED_OR_SELF_INTER_EDGES = 100,
SELF_INTER_EDGES = 200,
TURNING_EDGES = 300,
EMPHASIZED_EDGES = 400,
SHARP_EDGES = 500,
};
void MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter,
bool *inter, bool *leaky, int auxA = 0) const; bool *inter, bool *leaky, int auxA = 0) const;
void MakeOutlinesInto(SOutlineList *sel) const; void MakeOutlinesInto(SOutlineList *sel) const;

View File

@ -14,19 +14,19 @@ const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 };
const EntReqTable::TableEntry EntReqTable::Table[] = { const EntReqTable::TableEntry EntReqTable::Table[] = {
// request type entity type pts xtra? norml dist description // request type entity type pts xtra? norml dist description
{ Request::WORKPLANE, Entity::WORKPLANE, 1, false, true, false, "workplane" }, { Request::Type::WORKPLANE, Entity::Type::WORKPLANE, 1, false, true, false, "workplane" },
{ Request::DATUM_POINT, 0, 1, false, false, false, "datum-point" }, { Request::Type::DATUM_POINT, Entity::Type::DATUM_POINT, 1, false, false, false, "datum-point" },
{ Request::LINE_SEGMENT, Entity::LINE_SEGMENT, 2, false, false, false, "line-segment" }, { Request::Type::LINE_SEGMENT, Entity::Type::LINE_SEGMENT, 2, false, false, false, "line-segment" },
{ Request::CUBIC, Entity::CUBIC, 4, true, false, false, "cubic-bezier" }, { Request::Type::CUBIC, Entity::Type::CUBIC, 4, true, false, false, "cubic-bezier" },
{ Request::CUBIC_PERIODIC, Entity::CUBIC_PERIODIC, 3, true, false, false, "periodic-cubic" }, { Request::Type::CUBIC_PERIODIC, Entity::Type::CUBIC_PERIODIC, 3, true, false, false, "periodic-cubic" },
{ Request::CIRCLE, Entity::CIRCLE, 1, false, true, true, "circle" }, { Request::Type::CIRCLE, Entity::Type::CIRCLE, 1, false, true, true, "circle" },
{ Request::ARC_OF_CIRCLE, Entity::ARC_OF_CIRCLE, 3, false, true, false, "arc-of-circle" }, { Request::Type::ARC_OF_CIRCLE, Entity::Type::ARC_OF_CIRCLE, 3, false, true, false, "arc-of-circle" },
{ Request::TTF_TEXT, Entity::TTF_TEXT, 2, false, true, false, "ttf-text" }, { Request::Type::TTF_TEXT, Entity::Type::TTF_TEXT, 2, false, true, false, "ttf-text" },
{ 0, 0, 0, false, false, false, 0 }, { Request::Type::UNKNOWN, Entity::Type::UNKNOWN, 0, false, false, false, NULL },
}; };
const char *EntReqTable::DescriptionForRequest(int req) { const char *EntReqTable::DescriptionForRequest(Request::Type req) {
for(int i = 0; Table[i].reqType; i++) { for(int i = 0; Table[i].reqType != Request::Type::UNKNOWN; i++) {
if(req == Table[i].reqType) { if(req == Table[i].reqType) {
return Table[i].description; return Table[i].description;
} }
@ -35,7 +35,7 @@ const char *EntReqTable::DescriptionForRequest(int req) {
} }
void EntReqTable::CopyEntityInfo(const TableEntry *te, int extraPoints, void EntReqTable::CopyEntityInfo(const TableEntry *te, int extraPoints,
int *ent, int *req, int *pts, bool *hasNormal, bool *hasDistance) Entity::Type *ent, Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance)
{ {
int points = te->points; int points = te->points;
if(te->useExtraPoints) points += extraPoints; if(te->useExtraPoints) points += extraPoints;
@ -47,10 +47,10 @@ void EntReqTable::CopyEntityInfo(const TableEntry *te, int extraPoints,
if(hasDistance) *hasDistance = te->hasDistance; if(hasDistance) *hasDistance = te->hasDistance;
} }
bool EntReqTable::GetRequestInfo(int req, int extraPoints, bool EntReqTable::GetRequestInfo(Request::Type req, int extraPoints,
int *ent, int *pts, bool *hasNormal, bool *hasDistance) Entity::Type *ent, int *pts, bool *hasNormal, bool *hasDistance)
{ {
for(int i = 0; Table[i].reqType; i++) { for(int i = 0; Table[i].reqType != Request::Type::UNKNOWN; i++) {
const TableEntry *te = &(Table[i]); const TableEntry *te = &(Table[i]);
if(req == te->reqType) { if(req == te->reqType) {
CopyEntityInfo(te, extraPoints, CopyEntityInfo(te, extraPoints,
@ -61,10 +61,10 @@ bool EntReqTable::GetRequestInfo(int req, int extraPoints,
return false; return false;
} }
bool EntReqTable::GetEntityInfo(int ent, int extraPoints, bool EntReqTable::GetEntityInfo(Entity::Type ent, int extraPoints,
int *req, int *pts, bool *hasNormal, bool *hasDistance) Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance)
{ {
for(int i = 0; Table[i].reqType; i++) { for(int i = 0; Table[i].reqType != Request::Type::UNKNOWN; i++) {
const TableEntry *te = &(Table[i]); const TableEntry *te = &(Table[i]);
if(ent == te->entType) { if(ent == te->entType) {
CopyEntityInfo(te, extraPoints, CopyEntityInfo(te, extraPoints,
@ -75,8 +75,8 @@ bool EntReqTable::GetEntityInfo(int ent, int extraPoints,
return false; return false;
} }
int EntReqTable::GetRequestForEntity(int ent) { Request::Type EntReqTable::GetRequestForEntity(Entity::Type ent) {
int req = 0; Request::Type req = Request::Type::UNKNOWN;
GetEntityInfo(ent, 0, &req, NULL, NULL, NULL); GetEntityInfo(ent, 0, &req, NULL, NULL, NULL);
return req; return req;
} }
@ -86,7 +86,7 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
IdList<Param,hParam> *param) const IdList<Param,hParam> *param) const
{ {
int points = 0; int points = 0;
int et = 0; Entity::Type et = Entity::Type::UNKNOWN;
bool hasNormal = false; bool hasNormal = false;
bool hasDistance = false; bool hasDistance = false;
int i; int i;
@ -111,18 +111,18 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
Entity p = {}; Entity p = {};
p.workplane = workplane; p.workplane = workplane;
// points start from entity 1, except for datum point case // points start from entity 1, except for datum point case
p.h = h.entity(i+(et ? 1 : 0)); p.h = h.entity(i+((et != Entity::Type::DATUM_POINT) ? 1 : 0));
p.group = group; p.group = group;
p.style = style; p.style = style;
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
p.type = Entity::POINT_IN_3D; p.type = Entity::Type::POINT_IN_3D;
// params for x y z // params for x y z
p.param[0] = AddParam(param, h.param(16 + 3*i + 0)); p.param[0] = AddParam(param, h.param(16 + 3*i + 0));
p.param[1] = AddParam(param, h.param(16 + 3*i + 1)); p.param[1] = AddParam(param, h.param(16 + 3*i + 1));
p.param[2] = AddParam(param, h.param(16 + 3*i + 2)); p.param[2] = AddParam(param, h.param(16 + 3*i + 2));
} else { } else {
p.type = Entity::POINT_IN_2D; p.type = Entity::Type::POINT_IN_2D;
// params for u v // params for u v
p.param[0] = AddParam(param, h.param(16 + 3*i + 0)); p.param[0] = AddParam(param, h.param(16 + 3*i + 0));
p.param[1] = AddParam(param, h.param(16 + 3*i + 1)); p.param[1] = AddParam(param, h.param(16 + 3*i + 1));
@ -137,13 +137,13 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
n.group = group; n.group = group;
n.style = style; n.style = style;
if(workplane.v == Entity::FREE_IN_3D.v) { if(workplane.v == Entity::FREE_IN_3D.v) {
n.type = Entity::NORMAL_IN_3D; n.type = Entity::Type::NORMAL_IN_3D;
n.param[0] = AddParam(param, h.param(32+0)); n.param[0] = AddParam(param, h.param(32+0));
n.param[1] = AddParam(param, h.param(32+1)); n.param[1] = AddParam(param, h.param(32+1));
n.param[2] = AddParam(param, h.param(32+2)); n.param[2] = AddParam(param, h.param(32+2));
n.param[3] = AddParam(param, h.param(32+3)); n.param[3] = AddParam(param, h.param(32+3));
} else { } else {
n.type = Entity::NORMAL_IN_2D; n.type = Entity::Type::NORMAL_IN_2D;
// and this is just a copy of the workplane quaternion, // and this is just a copy of the workplane quaternion,
// so no params required // so no params required
} }
@ -160,13 +160,13 @@ void Request::Generate(IdList<Entity,hEntity> *entity,
d.h = h.entity(64); d.h = h.entity(64);
d.group = group; d.group = group;
d.style = style; d.style = style;
d.type = Entity::DISTANCE; d.type = Entity::Type::DISTANCE;
d.param[0] = AddParam(param, h.param(64)); d.param[0] = AddParam(param, h.param(64));
entity->Add(&d); entity->Add(&d);
e.distance = d.h; e.distance = d.h;
} }
if(et) entity->Add(&e); if(et != Entity::Type::DATUM_POINT) entity->Add(&e);
} }
std::string Request::DescriptionString() const { std::string Request::DescriptionString() const {
@ -185,7 +185,7 @@ std::string Request::DescriptionString() const {
} }
int Request::IndexOfPoint(hEntity he) const { int Request::IndexOfPoint(hEntity he) const {
if(type == DATUM_POINT) { if(type == Type::DATUM_POINT) {
return (he.v == h.entity(0).v) ? 0 : -1; return (he.v == h.entity(0).v) ? 0 : -1;
} }
for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) { for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) {

View File

@ -8,6 +8,11 @@
#ifndef __SKETCH_H #ifndef __SKETCH_H
#define __SKETCH_H #define __SKETCH_H
#ifdef WIN32
// winuser.h confilct (DIFFERENCE)
#undef DIFFERENCE
#endif
class hGroup; class hGroup;
class hRequest; class hRequest;
class hEntity; class hEntity;
@ -21,6 +26,29 @@ class Param;
class Equation; class Equation;
class Style; class Style;
enum class PolyError : uint32_t {
GOOD = 0,
NOT_CLOSED = 1,
NOT_COPLANAR = 2,
SELF_INTERSECTING = 3,
ZERO_LEN_EDGE = 4
};
enum class StipplePattern : uint32_t {
CONTINUOUS = 0,
DASH = 1,
LONG_DASH = 2,
DASH_DOT = 3,
DASH_DOT_DOT = 4,
DOT = 5,
FREEHAND = 6,
ZIGZAG = 7,
LAST = ZIGZAG
};
enum class Command : uint32_t;
// All of the hWhatever handles are a 32-bit ID, that is used to represent // All of the hWhatever handles are a 32-bit ID, that is used to represent
// some data structure in the sketch. // some data structure in the sketch.
class hGroup { class hGroup {
@ -91,7 +119,7 @@ public:
int tag; int tag;
hGroup h; hGroup h;
enum { enum class Type : uint32_t {
DRAWING_3D = 5000, DRAWING_3D = 5000,
DRAWING_WORKPLANE = 5001, DRAWING_WORKPLANE = 5001,
EXTRUDE = 5100, EXTRUDE = 5100,
@ -100,7 +128,7 @@ public:
TRANSLATE = 5201, TRANSLATE = 5201,
LINKED = 5300 LINKED = 5300
}; };
int type; Group::Type type;
int order; int order;
@ -121,12 +149,12 @@ public:
RgbaColor color; RgbaColor color;
struct { struct {
int how; SolveResult how;
int dof; int dof;
List<hConstraint> remove; List<hConstraint> remove;
} solved; } solved;
enum { enum class Subtype : uint32_t {
// For drawings in 2d // For drawings in 2d
WORKPLANE_BY_POINT_ORTHO = 6000, WORKPLANE_BY_POINT_ORTHO = 6000,
WORKPLANE_BY_LINE_SEGMENTS = 6001, WORKPLANE_BY_LINE_SEGMENTS = 6001,
@ -134,7 +162,7 @@ public:
ONE_SIDED = 7000, ONE_SIDED = 7000,
TWO_SIDED = 7001 TWO_SIDED = 7001
}; };
int subtype; Group::Subtype subtype;
bool skipFirst; // for step and repeat ops bool skipFirst; // for step and repeat ops
@ -151,15 +179,9 @@ public:
SPolygon polyLoops; SPolygon polyLoops;
SBezierLoopSetSet bezierLoops; SBezierLoopSetSet bezierLoops;
SBezierList bezierOpens; SBezierList bezierOpens;
enum {
POLY_GOOD = 0,
POLY_NOT_CLOSED = 1,
POLY_NOT_COPLANAR = 2,
POLY_SELF_INTERSECTING = 3,
POLY_ZERO_LEN_EDGE = 4
};
struct { struct {
int how; PolyError how;
SEdge notClosedAt; SEdge notClosedAt;
Vector errorPointAt; Vector errorPointAt;
} polyError; } polyError;
@ -177,12 +199,12 @@ public:
SEdgeList displayEdges; SEdgeList displayEdges;
SOutlineList displayOutlines; SOutlineList displayOutlines;
enum { enum class CombineAs : uint32_t {
COMBINE_AS_UNION = 0, UNION = 0,
COMBINE_AS_DIFFERENCE = 1, DIFFERENCE = 1,
COMBINE_AS_ASSEMBLE = 2 ASSEMBLE = 2
}; };
int meshCombine; CombineAs meshCombine;
bool forceToMesh; bool forceToMesh;
@ -249,9 +271,9 @@ public:
bool IsMeshGroup(); bool IsMeshGroup();
void GenerateShellAndMesh(); void GenerateShellAndMesh();
template<class T> void GenerateForStepAndRepeat(T *steps, T *outs); template<class T> void GenerateForStepAndRepeat(T *steps, T *outs);
template<class T> void GenerateForBoolean(T *a, T *b, T *o, int how); template<class T> void GenerateForBoolean(T *a, T *b, T *o, Group::CombineAs how);
void GenerateDisplayItems(); void GenerateDisplayItems();
void DrawDisplayItems(int t); void DrawDisplayItems(Group::Type t);
void Draw(); void Draw();
RgbaColor GetLoopSetFillColor(SBezierLoopSet *sbls, RgbaColor GetLoopSetFillColor(SBezierLoopSet *sbls,
bool *allSame, Vector *errorAt); bool *allSame, Vector *errorAt);
@ -260,7 +282,7 @@ public:
SPolygon GetPolygon(); SPolygon GetPolygon();
static void MenuGroup(int id); static void MenuGroup(Command id);
}; };
// A user request for some primitive or derived operation; for example a // A user request for some primitive or derived operation; for example a
@ -276,7 +298,8 @@ public:
hRequest h; hRequest h;
// Types of requests // Types of requests
enum { enum class Type : uint32_t {
UNKNOWN = 0,
WORKPLANE = 100, WORKPLANE = 100,
DATUM_POINT = 101, DATUM_POINT = 101,
LINE_SEGMENT = 200, LINE_SEGMENT = 200,
@ -287,7 +310,7 @@ public:
TTF_TEXT = 600 TTF_TEXT = 600
}; };
int type; Request::Type type;
int extraPoints; int extraPoints;
hEntity workplane; // or Entity::FREE_IN_3D hEntity workplane; // or Entity::FREE_IN_3D
@ -316,7 +339,9 @@ public:
static const hEntity FREE_IN_3D; static const hEntity FREE_IN_3D;
static const hEntity NO_ENTITY; static const hEntity NO_ENTITY;
enum { enum class Type : uint32_t {
DATUM_POINT = 0,
UNKNOWN = 1000,
POINT_IN_3D = 2000, POINT_IN_3D = 2000,
POINT_IN_2D = 2001, POINT_IN_2D = 2001,
POINT_N_TRANS = 2010, POINT_N_TRANS = 2010,
@ -349,7 +374,7 @@ public:
TTF_TEXT = 15000 TTF_TEXT = 15000
}; };
int type; Type type;
hGroup group; hGroup group;
hEntity workplane; // or Entity::FREE_IN_3D hEntity workplane; // or Entity::FREE_IN_3D
@ -493,7 +518,7 @@ public:
double dmin; double dmin;
double lineWidth; double lineWidth;
double stippleScale; double stippleScale;
int stippleType; StipplePattern stippleType;
int data; int data;
} dogd; // state for drawing or getting distance (for hit testing) } dogd; // state for drawing or getting distance (for hit testing)
@ -530,8 +555,8 @@ public:
class EntReqTable { class EntReqTable {
public: public:
typedef struct { typedef struct {
int reqType; Request::Type reqType;
int entType; Entity::Type entType;
int points; int points;
bool useExtraPoints; bool useExtraPoints;
bool hasNormal; bool hasNormal;
@ -541,14 +566,14 @@ public:
static const TableEntry Table[]; static const TableEntry Table[];
static const char *DescriptionForRequest(int req); static const char *DescriptionForRequest(Request::Type req);
static void CopyEntityInfo(const TableEntry *te, int extraPoints, static void CopyEntityInfo(const TableEntry *te, int extraPoints,
int *ent, int *req, int *pts, bool *hasNormal, bool *hasDistance); Entity::Type *ent, Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance);
static bool GetRequestInfo(int req, int extraPoints, static bool GetRequestInfo(Request::Type req, int extraPoints,
int *ent, int *pts, bool *hasNormal, bool *hasDistance); EntityBase::Type *ent, int *pts, bool *hasNormal, bool *hasDistance);
static bool GetEntityInfo(int ent, int extraPoints, static bool GetEntityInfo(EntityBase::Type ent, int extraPoints,
int *req, int *pts, bool *hasNormal, bool *hasDistance); Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance);
static int GetRequestForEntity(int ent); static Request::Type GetRequestForEntity(EntityBase::Type ent);
}; };
class Param { class Param {
@ -583,7 +608,8 @@ public:
static const hConstraint NO_CONSTRAINT; static const hConstraint NO_CONSTRAINT;
enum { enum class Type : uint32_t {
UNKNOWN = 0,
POINTS_COINCIDENT = 20, POINTS_COINCIDENT = 20,
PT_PT_DISTANCE = 30, PT_PT_DISTANCE = 30,
PT_PLANE_DISTANCE = 31, PT_PLANE_DISTANCE = 31,
@ -622,7 +648,7 @@ public:
COMMENT = 1000 COMMENT = 1000
}; };
int type; Type type;
hGroup group; hGroup group;
hEntity workplane; hEntity workplane;
@ -707,12 +733,12 @@ public:
static hConstraint AddConstraint(Constraint *c, bool rememberForUndo); static hConstraint AddConstraint(Constraint *c, bool rememberForUndo);
static hConstraint AddConstraint(Constraint *c); static hConstraint AddConstraint(Constraint *c);
static void MenuConstrain(int id); static void MenuConstrain(Command id);
static void DeleteAllConstraintsFor(int type, hEntity entityA, hEntity ptA); static void DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA);
static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB); static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB);
static hConstraint Constrain(int type, hEntity ptA, hEntity ptB, hEntity entityA); static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA);
static hConstraint Constrain(int type, hEntity ptA, hEntity ptB, static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB,
hEntity entityA, hEntity entityB, hEntity entityA, hEntity entityB,
bool other, bool other2); bool other, bool other2);
}; };
@ -741,19 +767,6 @@ public:
int tag; int tag;
hStyle h; hStyle h;
enum {
STIPPLE_CONTINUOUS = 0,
STIPPLE_DASH = 1,
STIPPLE_LONG_DASH = 2,
STIPPLE_DASH_DOT = 3,
STIPPLE_DASH_DOT_DOT = 4,
STIPPLE_DOT = 5,
STIPPLE_FREEHAND = 6,
STIPPLE_ZIGZAG = 7,
LAST_STIPPLE = STIPPLE_ZIGZAG
};
enum { enum {
// If an entity has no style, then it will be colored according to // If an entity has no style, then it will be colored according to
// whether the group that it's in is active or not, whether it's // whether the group that it's in is active or not, whether it's
@ -781,28 +794,29 @@ public:
std::string name; std::string name;
enum { enum class UnitsAs : uint32_t {
UNITS_AS_PIXELS = 0, PIXELS = 0,
UNITS_AS_MM = 1 MM = 1
}; };
double width; double width;
int widthAs; UnitsAs widthAs;
double textHeight; double textHeight;
int textHeightAs; UnitsAs textHeightAs;
enum { enum class TextOrigin : uint32_t {
ORIGIN_LEFT = 0x01, NONE = 0x00,
ORIGIN_RIGHT = 0x02, LEFT = 0x01,
ORIGIN_BOT = 0x04, RIGHT = 0x02,
ORIGIN_TOP = 0x08 BOT = 0x04,
TOP = 0x08
}; };
int textOrigin; TextOrigin textOrigin;
double textAngle; double textAngle;
RgbaColor color; RgbaColor color;
bool filled; bool filled;
RgbaColor fillColor; RgbaColor fillColor;
bool visible; bool visible;
bool exportable; bool exportable;
int stippleType; StipplePattern stippleType;
double stippleScale; double stippleScale;
int zIndex; int zIndex;
@ -844,7 +858,7 @@ public:
static double DefaultTextHeight(); static double DefaultTextHeight();
static bool Exportable(int hs); static bool Exportable(int hs);
static hStyle ForEntity(hEntity he); static hStyle ForEntity(hEntity he);
static int PatternType(hStyle hs); static StipplePattern PatternType(hStyle hs);
static double StippleScaleMm(hStyle hs); static double StippleScaleMm(hStyle hs);
std::string DescriptionString() const; std::string DescriptionString() const;
@ -895,7 +909,7 @@ inline hConstraint hEquation::constraint() const
// The format for entities stored on the clipboard. // The format for entities stored on the clipboard.
class ClipboardRequest { class ClipboardRequest {
public: public:
int type; Request::Type type;
int extraPoints; int extraPoints;
hStyle style; hStyle style;
std::string str; std::string str;

View File

@ -19,7 +19,6 @@ void SolveSpaceUI::Init() {
SS.tangentArcRadius = 10.0; SS.tangentArcRadius = 10.0;
// Then, load the registry settings. // Then, load the registry settings.
int i;
// Default list of colors for the model material // Default list of colors for the model material
modelColor[0] = CnfThawColor(RGBi(150, 150, 150), "ModelColor_0"); modelColor[0] = CnfThawColor(RGBi(150, 150, 150), "ModelColor_0");
modelColor[1] = CnfThawColor(RGBi(100, 100, 100), "ModelColor_1"); modelColor[1] = CnfThawColor(RGBi(100, 100, 100), "ModelColor_1");
@ -51,7 +50,7 @@ void SolveSpaceUI::Init() {
// Max pwl segments to generate // Max pwl segments to generate
exportMaxSegments = CnfThawInt(64, "ExportMaxSegments"); exportMaxSegments = CnfThawInt(64, "ExportMaxSegments");
// View units // View units
viewUnits = (Unit)CnfThawInt((uint32_t)UNIT_MM, "ViewUnits"); viewUnits = (Unit)CnfThawInt((uint32_t)Unit::MM, "ViewUnits");
// Number of digits after the decimal point // Number of digits after the decimal point
afterDecimalMm = CnfThawInt(2, "AfterDecimalMm"); afterDecimalMm = CnfThawInt(2, "AfterDecimalMm");
afterDecimalInch = CnfThawInt(3, "AfterDecimalInch"); afterDecimalInch = CnfThawInt(3, "AfterDecimalInch");
@ -95,7 +94,7 @@ void SolveSpaceUI::Init() {
// Show toolbar in the graphics window // Show toolbar in the graphics window
showToolbar = CnfThawBool(true, "ShowToolbar"); showToolbar = CnfThawBool(true, "ShowToolbar");
// Recent files menus // Recent files menus
for(i = 0; i < MAX_RECENT; i++) { for(size_t i = 0; i < MAX_RECENT; i++) {
RecentFile[i] = CnfThawString("", "RecentFile_" + std::to_string(i)); RecentFile[i] = CnfThawString("", "RecentFile_" + std::to_string(i));
} }
RefreshRecentMenus(); RefreshRecentMenus();
@ -148,10 +147,10 @@ bool SolveSpaceUI::OpenFile(const std::string &filename) {
void SolveSpaceUI::Exit() { void SolveSpaceUI::Exit() {
// Recent files // Recent files
for(int i = 0; i < MAX_RECENT; i++) for(size_t i = 0; i < MAX_RECENT; i++)
CnfFreezeString(RecentFile[i], "RecentFile_" + std::to_string(i)); CnfFreezeString(RecentFile[i], "RecentFile_" + std::to_string(i));
// Model colors // Model colors
for(int i = 0; i < MODEL_COLORS; i++) for(size_t i = 0; i < MODEL_COLORS; i++)
CnfFreezeColor(modelColor[i], "ModelColor_" + std::to_string(i)); CnfFreezeColor(modelColor[i], "ModelColor_" + std::to_string(i));
// Light intensities // Light intensities
CnfFreezeFloat((float)lightIntensity[0], "LightIntensity_0"); CnfFreezeFloat((float)lightIntensity[0], "LightIntensity_0");
@ -246,21 +245,21 @@ void SolveSpaceUI::DoLater() {
} }
double SolveSpaceUI::MmPerUnit() { double SolveSpaceUI::MmPerUnit() {
if(viewUnits == UNIT_INCHES) { if(viewUnits == Unit::INCHES) {
return 25.4; return 25.4;
} else { } else {
return 1.0; return 1.0;
} }
} }
const char *SolveSpaceUI::UnitName() { const char *SolveSpaceUI::UnitName() {
if(viewUnits == UNIT_INCHES) { if(viewUnits == Unit::INCHES) {
return "inch"; return "inch";
} else { } else {
return "mm"; return "mm";
} }
} }
std::string SolveSpaceUI::MmToString(double v) { std::string SolveSpaceUI::MmToString(double v) {
if(viewUnits == UNIT_INCHES) { if(viewUnits == Unit::INCHES) {
return ssprintf("%.*f", afterDecimalInch, v/25.4); return ssprintf("%.*f", afterDecimalInch, v/25.4);
} else { } else {
return ssprintf("%.*f", afterDecimalMm, v); return ssprintf("%.*f", afterDecimalMm, v);
@ -284,10 +283,10 @@ int SolveSpaceUI::GetMaxSegments() {
return maxSegments; return maxSegments;
} }
int SolveSpaceUI::UnitDigitsAfterDecimal() { int SolveSpaceUI::UnitDigitsAfterDecimal() {
return (viewUnits == UNIT_INCHES) ? afterDecimalInch : afterDecimalMm; return (viewUnits == Unit::INCHES) ? afterDecimalInch : afterDecimalMm;
} }
void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) { void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) {
if(viewUnits == UNIT_INCHES) { if(viewUnits == Unit::INCHES) {
afterDecimalInch = v; afterDecimalInch = v;
} else { } else {
afterDecimalMm = v; afterDecimalMm = v;
@ -320,7 +319,7 @@ void SolveSpaceUI::AfterNewFile() {
SS.GW.projRight = Vector::From(1, 0, 0); SS.GW.projRight = Vector::From(1, 0, 0);
SS.GW.projUp = Vector::From(0, 1, 0); SS.GW.projUp = Vector::From(0, 1, 0);
GenerateAll(GENERATE_REGEN); GenerateAll(Generate::REGEN);
TW.Init(); TW.Init();
GW.Init(); GW.Init();
@ -338,7 +337,7 @@ void SolveSpaceUI::AfterNewFile() {
// thing visible is the not-yet-generated surfaces. // thing visible is the not-yet-generated surfaces.
GW.ZoomToFit(true); GW.ZoomToFit(true);
GenerateAll(GENERATE_ALL); GenerateAll(Generate::ALL);
SS.ScheduleShowTW(); SS.ScheduleShowTW();
// Then zoom to fit again, to fit the triangles // Then zoom to fit again, to fit the triangles
GW.ZoomToFit(false); GW.ZoomToFit(false);
@ -351,22 +350,20 @@ void SolveSpaceUI::AfterNewFile() {
} }
void SolveSpaceUI::RemoveFromRecentList(const std::string &filename) { void SolveSpaceUI::RemoveFromRecentList(const std::string &filename) {
int src, dest; int dest = 0;
dest = 0; for(int src = 0; src < (int)MAX_RECENT; src++) {
for(src = 0; src < MAX_RECENT; src++) {
if(filename != RecentFile[src]) { if(filename != RecentFile[src]) {
if(src != dest) RecentFile[dest] = RecentFile[src]; if(src != dest) RecentFile[dest] = RecentFile[src];
dest++; dest++;
} }
} }
while(dest < MAX_RECENT) RecentFile[dest++].clear(); while(dest < (int)MAX_RECENT) RecentFile[dest++].clear();
RefreshRecentMenus(); RefreshRecentMenus();
} }
void SolveSpaceUI::AddToRecentList(const std::string &filename) { void SolveSpaceUI::AddToRecentList(const std::string &filename) {
RemoveFromRecentList(filename); RemoveFromRecentList(filename);
int src; for(int src = MAX_RECENT - 2; src >= 0; src--) {
for(src = MAX_RECENT - 2; src >= 0; src--) {
RecentFile[src+1] = RecentFile[src]; RecentFile[src+1] = RecentFile[src];
} }
RecentFile[0] = filename; RecentFile[0] = filename;
@ -438,17 +435,18 @@ static std::string Extension(const std::string &filename) {
return ""; return "";
} }
void SolveSpaceUI::MenuFile(int id) { void SolveSpaceUI::MenuFile(Command id) {
if(id >= RECENT_OPEN && id < (RECENT_OPEN+MAX_RECENT)) { if((uint32_t)id >= (uint32_t)Command::RECENT_OPEN &&
(uint32_t)id < ((uint32_t)Command::RECENT_OPEN+MAX_RECENT)) {
if(!SS.OkayToStartNewFile()) return; if(!SS.OkayToStartNewFile()) return;
std::string newFile = RecentFile[id - RECENT_OPEN]; std::string newFile = RecentFile[(uint32_t)id - (uint32_t)Command::RECENT_OPEN];
SS.OpenFile(newFile); SS.OpenFile(newFile);
return; return;
} }
switch(id) { switch(id) {
case GraphicsWindow::MNU_NEW: case Command::NEW:
if(!SS.OkayToStartNewFile()) break; if(!SS.OkayToStartNewFile()) break;
SS.saveFile = ""; SS.saveFile = "";
@ -456,7 +454,7 @@ void SolveSpaceUI::MenuFile(int id) {
SS.AfterNewFile(); SS.AfterNewFile();
break; break;
case GraphicsWindow::MNU_OPEN: { case Command::OPEN: {
if(!SS.OkayToStartNewFile()) break; if(!SS.OkayToStartNewFile()) break;
std::string newFile; std::string newFile;
@ -466,22 +464,22 @@ void SolveSpaceUI::MenuFile(int id) {
break; break;
} }
case GraphicsWindow::MNU_SAVE: case Command::SAVE:
SS.GetFilenameAndSave(false); SS.GetFilenameAndSave(false);
break; break;
case GraphicsWindow::MNU_SAVE_AS: case Command::SAVE_AS:
SS.GetFilenameAndSave(true); SS.GetFilenameAndSave(true);
break; break;
case GraphicsWindow::MNU_EXPORT_PNG: { case Command::EXPORT_PNG: {
std::string exportFile; std::string exportFile;
if(!GetSaveFile(&exportFile, "", PngFileFilter)) break; if(!GetSaveFile(&exportFile, "", PngFileFilter)) break;
SS.ExportAsPngTo(exportFile); SS.ExportAsPngTo(exportFile);
break; break;
} }
case GraphicsWindow::MNU_EXPORT_VIEW: { case Command::EXPORT_VIEW: {
std::string exportFile; std::string exportFile;
if(!GetSaveFile(&exportFile, CnfThawString("", "ViewExportFormat"), if(!GetSaveFile(&exportFile, CnfThawString("", "ViewExportFormat"),
VectorFileFilter)) break; VectorFileFilter)) break;
@ -503,7 +501,7 @@ void SolveSpaceUI::MenuFile(int id) {
break; break;
} }
case GraphicsWindow::MNU_EXPORT_WIREFRAME: { case Command::EXPORT_WIREFRAME: {
std::string exportFile; std::string exportFile;
if(!GetSaveFile(&exportFile, CnfThawString("", "WireframeExportFormat"), if(!GetSaveFile(&exportFile, CnfThawString("", "WireframeExportFormat"),
Vector3dFileFilter)) break; Vector3dFileFilter)) break;
@ -513,7 +511,7 @@ void SolveSpaceUI::MenuFile(int id) {
break; break;
} }
case GraphicsWindow::MNU_EXPORT_SECTION: { case Command::EXPORT_SECTION: {
std::string exportFile; std::string exportFile;
if(!GetSaveFile(&exportFile, CnfThawString("", "SectionExportFormat"), if(!GetSaveFile(&exportFile, CnfThawString("", "SectionExportFormat"),
VectorFileFilter)) break; VectorFileFilter)) break;
@ -523,7 +521,7 @@ void SolveSpaceUI::MenuFile(int id) {
break; break;
} }
case GraphicsWindow::MNU_EXPORT_MESH: { case Command::EXPORT_MESH: {
std::string exportFile; std::string exportFile;
if(!GetSaveFile(&exportFile, CnfThawString("", "MeshExportFormat"), if(!GetSaveFile(&exportFile, CnfThawString("", "MeshExportFormat"),
MeshFileFilter)) break; MeshFileFilter)) break;
@ -533,7 +531,7 @@ void SolveSpaceUI::MenuFile(int id) {
break; break;
} }
case GraphicsWindow::MNU_EXPORT_SURFACES: { case Command::EXPORT_SURFACES: {
std::string exportFile; std::string exportFile;
if(!GetSaveFile(&exportFile, CnfThawString("", "SurfacesExportFormat"), if(!GetSaveFile(&exportFile, CnfThawString("", "SurfacesExportFormat"),
SurfaceFileFilter)) break; SurfaceFileFilter)) break;
@ -544,7 +542,7 @@ void SolveSpaceUI::MenuFile(int id) {
break; break;
} }
case GraphicsWindow::MNU_IMPORT: { case Command::IMPORT: {
std::string importFile; std::string importFile;
if(!GetOpenFile(&importFile, CnfThawString("", "ImportFormat"), if(!GetOpenFile(&importFile, CnfThawString("", "ImportFormat"),
ImportableFileFilter)) break; ImportableFileFilter)) break;
@ -556,12 +554,12 @@ void SolveSpaceUI::MenuFile(int id) {
ImportDwg(importFile); ImportDwg(importFile);
} else ssassert(false, "Unexpected extension of file to import"); } else ssassert(false, "Unexpected extension of file to import");
SS.GenerateAll(SolveSpaceUI::GENERATE_UNTIL_ACTIVE); SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE);
SS.ScheduleShowTW(); SS.ScheduleShowTW();
break; break;
} }
case GraphicsWindow::MNU_EXIT: case Command::EXIT:
if(!SS.OkayToStartNewFile()) break; if(!SS.OkayToStartNewFile()) break;
SS.Exit(); SS.Exit();
break; break;
@ -572,23 +570,23 @@ void SolveSpaceUI::MenuFile(int id) {
SS.UpdateWindowTitle(); SS.UpdateWindowTitle();
} }
void SolveSpaceUI::MenuAnalyze(int id) { void SolveSpaceUI::MenuAnalyze(Command id) {
SS.GW.GroupSelection(); SS.GW.GroupSelection();
#define gs (SS.GW.gs) #define gs (SS.GW.gs)
switch(id) { switch(id) {
case GraphicsWindow::MNU_STEP_DIM: case Command::STEP_DIM:
if(gs.constraints == 1 && gs.n == 0) { if(gs.constraints == 1 && gs.n == 0) {
Constraint *c = SK.GetConstraint(gs.constraint[0]); Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->HasLabel() && !c->reference) { if(c->HasLabel() && !c->reference) {
SS.TW.shown.dimFinish = c->valA; SS.TW.shown.dimFinish = c->valA;
SS.TW.shown.dimSteps = 10; SS.TW.shown.dimSteps = 10;
SS.TW.shown.dimIsDistance = SS.TW.shown.dimIsDistance =
(c->type != Constraint::ANGLE) && (c->type != Constraint::Type::ANGLE) &&
(c->type != Constraint::LENGTH_RATIO) && (c->type != Constraint::Type::LENGTH_RATIO) &&
(c->type != Constraint::LENGTH_DIFFERENCE); (c->type != Constraint::Type::LENGTH_DIFFERENCE);
SS.TW.shown.constraint = c->h; SS.TW.shown.constraint = c->h;
SS.TW.shown.screen = TextWindow::SCREEN_STEP_DIMENSION; SS.TW.shown.screen = TextWindow::Screen::STEP_DIMENSION;
// The step params are specified in the text window, // The step params are specified in the text window,
// so force that to be shown. // so force that to be shown.
@ -605,7 +603,7 @@ void SolveSpaceUI::MenuAnalyze(int id) {
} }
break; break;
case GraphicsWindow::MNU_NAKED_EDGES: { case Command::NAKED_EDGES: {
SS.nakedEdges.Clear(); SS.nakedEdges.Clear();
Group *g = SK.GetGroup(SS.GW.activeGroup); Group *g = SK.GetGroup(SS.GW.activeGroup);
@ -613,7 +611,7 @@ void SolveSpaceUI::MenuAnalyze(int id) {
SKdNode *root = SKdNode::From(m); SKdNode *root = SKdNode::From(m);
bool inters, leaks; bool inters, leaks;
root->MakeCertainEdgesInto(&(SS.nakedEdges), root->MakeCertainEdgesInto(&(SS.nakedEdges),
SKdNode::NAKED_OR_SELF_INTER_EDGES, true, &inters, &leaks); EdgeKind::NAKED_OR_SELF_INTER, true, &inters, &leaks);
InvalidateGraphics(); InvalidateGraphics();
@ -637,14 +635,14 @@ void SolveSpaceUI::MenuAnalyze(int id) {
break; break;
} }
case GraphicsWindow::MNU_INTERFERENCE: { case Command::INTERFERENCE: {
SS.nakedEdges.Clear(); SS.nakedEdges.Clear();
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh); SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
SKdNode *root = SKdNode::From(m); SKdNode *root = SKdNode::From(m);
bool inters, leaks; bool inters, leaks;
root->MakeCertainEdgesInto(&(SS.nakedEdges), root->MakeCertainEdgesInto(&(SS.nakedEdges),
SKdNode::SELF_INTER_EDGES, false, &inters, &leaks); EdgeKind::SELF_INTER, false, &inters, &leaks);
InvalidateGraphics(); InvalidateGraphics();
@ -657,7 +655,7 @@ void SolveSpaceUI::MenuAnalyze(int id) {
break; break;
} }
case GraphicsWindow::MNU_VOLUME: { case Command::VOLUME: {
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh); SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
double vol = 0; double vol = 0;
@ -717,7 +715,7 @@ void SolveSpaceUI::MenuAnalyze(int id) {
vol / pow(SS.MmPerUnit(), 3), vol / pow(SS.MmPerUnit(), 3),
SS.UnitName()); SS.UnitName());
if(SS.viewUnits == SolveSpaceUI::UNIT_MM) { if(SS.viewUnits == Unit::MM) {
msg += ssprintf("\n %.2f mL", vol/(10*10*10)); msg += ssprintf("\n %.2f mL", vol/(10*10*10));
} }
msg += "\n\nCurved surfaces have been approximated as triangles.\n" msg += "\n\nCurved surfaces have been approximated as triangles.\n"
@ -726,9 +724,9 @@ void SolveSpaceUI::MenuAnalyze(int id) {
break; break;
} }
case GraphicsWindow::MNU_AREA: { case Command::AREA: {
Group *g = SK.GetGroup(SS.GW.activeGroup); Group *g = SK.GetGroup(SS.GW.activeGroup);
if(g->polyError.how != Group::POLY_GOOD) { if(g->polyError.how != PolyError::GOOD) {
Error("This group does not contain a correctly-formed " Error("This group does not contain a correctly-formed "
"2d closed area. It is open, not coplanar, or self-" "2d closed area. It is open, not coplanar, or self-"
"intersecting."); "intersecting.");
@ -753,13 +751,13 @@ void SolveSpaceUI::MenuAnalyze(int id) {
break; break;
} }
case GraphicsWindow::MNU_SHOW_DOF: case Command::SHOW_DOF:
// This works like a normal solve, except that it calculates // This works like a normal solve, except that it calculates
// which variables are free/bound at the same time. // which variables are free/bound at the same time.
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL, true); SS.GenerateAll(SolveSpaceUI::Generate::ALL, true);
break; break;
case GraphicsWindow::MNU_TRACE_PT: case Command::TRACE_PT:
if(gs.points == 1 && gs.n == 1) { if(gs.points == 1 && gs.n == 1) {
SS.traced.point = gs.point[0]; SS.traced.point = gs.point[0];
SS.GW.ClearSelection(); SS.GW.ClearSelection();
@ -768,7 +766,7 @@ void SolveSpaceUI::MenuAnalyze(int id) {
} }
break; break;
case GraphicsWindow::MNU_STOP_TRACING: { case Command::STOP_TRACING: {
std::string exportFile; std::string exportFile;
if(GetSaveFile(&exportFile, "", CsvFileFilter)) { if(GetSaveFile(&exportFile, "", CsvFileFilter)) {
FILE *f = ssfopen(exportFile, "wb"); FILE *f = ssfopen(exportFile, "wb");
@ -797,13 +795,13 @@ void SolveSpaceUI::MenuAnalyze(int id) {
} }
} }
void SolveSpaceUI::MenuHelp(int id) { void SolveSpaceUI::MenuHelp(Command id) {
switch(id) { switch(id) {
case GraphicsWindow::MNU_WEBSITE: case Command::WEBSITE:
OpenWebsite("http://solvespace.com/helpmenu"); OpenWebsite("http://solvespace.com/helpmenu");
break; break;
case GraphicsWindow::MNU_ABOUT: case Command::ABOUT:
Message( Message(
"This is SolveSpace version " PACKAGE_VERSION ".\n" "This is SolveSpace version " PACKAGE_VERSION ".\n"
"\n" "\n"
@ -855,8 +853,8 @@ BBox Sketch::CalculateEntityBBox(bool includingInvisible) {
point = e->PointGetNum(); point = e->PointGetNum();
} else { } else {
switch(e->type) { switch(e->type) {
case Entity::ARC_OF_CIRCLE: case Entity::Type::ARC_OF_CIRCLE:
case Entity::CIRCLE: case Entity::Type::CIRCLE:
r = e->CircleGetRadiusNum(); r = e->CircleGetRadiusNum();
point = GetEntity(e->point[0])->PointGetNum(); point = GetEntity(e->point[0])->PointGetNum();
break; break;

View File

@ -141,6 +141,8 @@ class Expr;
class ExprVector; class ExprVector;
class ExprQuaternion; class ExprQuaternion;
class RgbaColor; class RgbaColor;
enum class Command : uint32_t;
enum class ContextCommand : uint32_t;
//================ //================
// From the platform-specific code. // From the platform-specific code.
@ -153,9 +155,7 @@ class RgbaColor;
FILE *ssfopen(const std::string &filename, const char *mode); FILE *ssfopen(const std::string &filename, const char *mode);
void ssremove(const std::string &filename); void ssremove(const std::string &filename);
#define MAX_RECENT 8 const size_t MAX_RECENT = 8;
#define RECENT_OPEN (0xf000)
#define RECENT_LINK (0xf100)
extern std::string RecentFile[MAX_RECENT]; extern std::string RecentFile[MAX_RECENT];
void RefreshRecentMenus(); void RefreshRecentMenus();
@ -223,6 +223,11 @@ const FileFilter CsvFileFilter[] = {
{ NULL, {} } { NULL, {} }
}; };
enum class Unit : uint32_t {
MM = 0,
INCHES
};
bool GetSaveFile(std::string *filename, const std::string &defExtension, bool GetSaveFile(std::string *filename, const std::string &defExtension,
const FileFilter filters[]); const FileFilter filters[]);
bool GetOpenFile(std::string *filename, const std::string &defExtension, bool GetOpenFile(std::string *filename, const std::string &defExtension,
@ -231,9 +236,9 @@ std::vector<std::string> GetFontFiles();
void OpenWebsite(const char *url); void OpenWebsite(const char *url);
void CheckMenuById(int id, bool checked); void CheckMenuByCmd(Command id, bool checked);
void RadioMenuById(int id, bool selected); void RadioMenuByCmd(Command id, bool selected);
void EnableMenuById(int id, bool enabled); void EnableMenuByCmd(Command id, bool enabled);
void ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars, void ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars,
const std::string &str); const std::string &str);
@ -244,11 +249,9 @@ void HideTextEditControl();
bool TextEditControlIsVisible(); bool TextEditControlIsVisible();
void MoveTextScrollbarTo(int pos, int maxPos, int page); void MoveTextScrollbarTo(int pos, int maxPos, int page);
#define CONTEXT_SUBMENU (-1) void AddContextMenuItem(const char *legend, ContextCommand id);
#define CONTEXT_SEPARATOR (-2)
void AddContextMenuItem(const char *legend, int id);
void CreateContextSubmenu(); void CreateContextSubmenu();
int ShowContextMenu(); ContextCommand ShowContextMenu();
void ToggleMenuBar(); void ToggleMenuBar();
bool MenuBarIsVisible(); bool MenuBarIsVisible();
@ -308,6 +311,15 @@ class hParam;
typedef IdList<Entity,hEntity> EntityList; typedef IdList<Entity,hEntity> EntityList;
typedef IdList<Param,hParam> ParamList; typedef IdList<Param,hParam> ParamList;
enum class SolveResult : uint32_t {
OKAY = 0,
DIDNT_CONVERGE = 10,
REDUNDANT_OKAY = 11,
REDUNDANT_DIDNT_CONVERGE = 12,
TOO_MANY_UNKNOWNS = 20
};
#include "sketch.h" #include "sketch.h"
#include "ui.h" #include "ui.h"
#include "expr.h" #include "expr.h"
@ -362,7 +374,7 @@ double ssglStrFontSize(double h);
double ssglStrWidth(const std::string &str, double h); double ssglStrWidth(const std::string &str, double h);
void ssglLockColorTo(RgbaColor rgb); void ssglLockColorTo(RgbaColor rgb);
void ssglStippledLine(Vector a, Vector b, double width, void ssglStippledLine(Vector a, Vector b, double width,
int stippleType, double stippleScale, bool maybeFat); StipplePattern stippleType, double stippleScale, bool maybeFat);
void ssglStippledLine(Vector a, Vector b, double width, void ssglStippledLine(Vector a, Vector b, double width,
const char *stipplePattern, double stippleScale, bool maybeFat); const char *stipplePattern, double stippleScale, bool maybeFat);
void ssglFatLine(Vector a, Vector b, double width); void ssglFatLine(Vector a, Vector b, double width);
@ -467,14 +479,7 @@ public:
bool NewtonSolve(int tag); bool NewtonSolve(int tag);
enum { SolveResult Solve(Group *g, int *dof, List<hConstraint> *bad,
SOLVED_OKAY = 0,
DIDNT_CONVERGE = 10,
REDUNDANT_OKAY = 11,
REDUNDANT_DIDNT_CONVERGE = 12,
TOO_MANY_UNKNOWNS = 20
};
int Solve(Group *g, int *dof, List<hConstraint> *bad,
bool andFindBad, bool andFindFree); bool andFindBad, bool andFindFree);
void Clear(); void Clear();
@ -543,7 +548,7 @@ public:
std::vector<BezierPath> paths; std::vector<BezierPath> paths;
IdList<Constraint,hConstraint> *constraint; IdList<Constraint,hConstraint> *constraint;
static const char *lineTypeName(int stippleType); static const char *lineTypeName(StipplePattern stippleType);
bool OutputConstraints(IdList<Constraint,hConstraint> *constraint) override; bool OutputConstraints(IdList<Constraint,hConstraint> *constraint) override;
@ -771,10 +776,6 @@ public:
float plungeFeed; float plungeFeed;
} gCode; } gCode;
typedef enum {
UNIT_MM = 0,
UNIT_INCHES
} Unit;
Unit viewUnits; Unit viewUnits;
int afterDecimalMm; int afterDecimalMm;
int afterDecimalInch; int afterDecimalInch;
@ -830,7 +831,7 @@ public:
Constraint c; Constraint c;
Style s; Style s;
} sv; } sv;
static void MenuFile(int id); static void MenuFile(Command id);
bool Autosave(); bool Autosave();
void RemoveAutosave(); void RemoveAutosave();
bool GetFilenameAndSave(bool saveAs); bool GetFilenameAndSave(bool saveAs);
@ -862,7 +863,7 @@ public:
double cameraTan, double cameraTan,
VectorFileWriter *out); VectorFileWriter *out);
static void MenuAnalyze(int id); static void MenuAnalyze(Command id);
// Additional display stuff // Additional display stuff
struct { struct {
@ -915,14 +916,14 @@ public:
bool PruneRequests(hGroup hg); bool PruneRequests(hGroup hg);
bool PruneConstraints(hGroup hg); bool PruneConstraints(hGroup hg);
enum GenerateType { enum class Generate : uint32_t {
GENERATE_DIRTY, DIRTY,
GENERATE_ALL, ALL,
GENERATE_REGEN, REGEN,
GENERATE_UNTIL_ACTIVE, UNTIL_ACTIVE,
}; };
void GenerateAll(GenerateType type = GENERATE_DIRTY, bool andFindFree = false, void GenerateAll(Generate type = Generate::DIRTY, bool andFindFree = false,
bool genForBBox = false); bool genForBBox = false);
void SolveGroup(hGroup hg, bool andFindFree); void SolveGroup(hGroup hg, bool andFindFree);
void MarkDraggedParams(); void MarkDraggedParams();
@ -951,7 +952,7 @@ public:
void ScheduleGenerateAll(); void ScheduleGenerateAll();
void DoLater(); void DoLater();
static void MenuHelp(int id); static void MenuHelp(Command id);
void Clear(); void Clear();

View File

@ -9,11 +9,11 @@
static int I; static int I;
void SShell::MakeFromUnionOf(SShell *a, SShell *b) { void SShell::MakeFromUnionOf(SShell *a, SShell *b) {
MakeFromBoolean(a, b, AS_UNION); MakeFromBoolean(a, b, SSurface::CombineAs::UNION);
} }
void SShell::MakeFromDifferenceOf(SShell *a, SShell *b) { void SShell::MakeFromDifferenceOf(SShell *a, SShell *b) {
MakeFromBoolean(a, b, AS_DIFFERENCE); MakeFromBoolean(a, b, SSurface::CombineAs::DIFFERENCE);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -83,8 +83,8 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
// some slop if points are close to edge and pwl is too coarse, // some slop if points are close to edge and pwl is too coarse,
// and it doesn't hurt to split unnecessarily. // and it doesn't hurt to split unnecessarily.
Point2d dummy = { 0, 0 }; Point2d dummy = { 0, 0 };
int c = (pi->srf->bsp) ? pi->srf->bsp->ClassifyPoint(puv, dummy, pi->srf) : SBspUv::OUTSIDE; SBspUv::Class c = (pi->srf->bsp) ? pi->srf->bsp->ClassifyPoint(puv, dummy, pi->srf) : SBspUv::Class::OUTSIDE;
if(c == SBspUv::OUTSIDE) { if(c == SBspUv::Class::OUTSIDE) {
double d = VERY_POSITIVE; double d = VERY_POSITIVE;
if(pi->srf->bsp) d = pi->srf->bsp->MinimumDistanceToEdge(puv, pi->srf); if(pi->srf->bsp) d = pi->srf->bsp->MinimumDistanceToEdge(puv, pi->srf);
if(d > SS.ChordTolMm()) { if(d > SS.ChordTolMm()) {
@ -135,7 +135,7 @@ void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) {
SCurve scn = sc->MakeCopySplitAgainst(agnst, NULL, SCurve scn = sc->MakeCopySplitAgainst(agnst, NULL,
surface.FindById(sc->surfA), surface.FindById(sc->surfA),
surface.FindById(sc->surfB)); surface.FindById(sc->surfB));
scn.source = opA ? SCurve::FROM_A : SCurve::FROM_B; scn.source = opA ? SCurve::Source::A : SCurve::Source::B;
hSCurve hsc = into->curve.AddAndAssignId(&scn); hSCurve hsc = into->curve.AddAndAssignId(&scn);
// And note the new ID so that we can rewrite the trims appropriately // And note the new ID so that we can rewrite the trims appropriately
@ -194,12 +194,12 @@ void SSurface::TrimFromEdgeList(SEdgeList *el, bool asUv) {
} }
} }
static bool KeepRegion(int type, bool opA, int shell, int orig) static bool KeepRegion(SSurface::CombineAs type, bool opA, SShell::Class shell, SShell::Class orig)
{ {
bool inShell = (shell == SShell::INSIDE), bool inShell = (shell == SShell::Class::INSIDE),
inSame = (shell == SShell::COINC_SAME), inSame = (shell == SShell::Class::COINC_SAME),
inOpp = (shell == SShell::COINC_OPP), inOpp = (shell == SShell::Class::COINC_OPP),
inOrig = (orig == SShell::INSIDE); inOrig = (orig == SShell::Class::INSIDE);
bool inFace = inSame || inOpp; bool inFace = inSame || inOpp;
@ -207,14 +207,14 @@ static bool KeepRegion(int type, bool opA, int shell, int orig)
// if inFace is true. // if inFace is true.
if(!inOrig) return false; if(!inOrig) return false;
switch(type) { switch(type) {
case SShell::AS_UNION: case SSurface::CombineAs::UNION:
if(opA) { if(opA) {
return (!inShell && !inFace); return (!inShell && !inFace);
} else { } else {
return (!inShell && !inFace) || inSame; return (!inShell && !inFace) || inSame;
} }
case SShell::AS_DIFFERENCE: case SSurface::CombineAs::DIFFERENCE:
if(opA) { if(opA) {
return (!inShell && !inFace); return (!inShell && !inFace);
} else { } else {
@ -224,9 +224,9 @@ static bool KeepRegion(int type, bool opA, int shell, int orig)
default: ssassert(false, "Unexpected shell type"); default: ssassert(false, "Unexpected shell type");
} }
} }
static bool KeepEdge(int type, bool opA, static bool KeepEdge(SSurface::CombineAs type, bool opA,
int indir_shell, int outdir_shell, SShell::Class indir_shell, SShell::Class outdir_shell,
int indir_orig, int outdir_orig) SShell::Class indir_orig, SShell::Class outdir_orig)
{ {
bool keepIn = KeepRegion(type, opA, indir_shell, indir_orig), bool keepIn = KeepRegion(type, opA, indir_shell, indir_orig),
keepOut = KeepRegion(type, opA, outdir_shell, outdir_orig); keepOut = KeepRegion(type, opA, outdir_shell, outdir_orig);
@ -237,33 +237,33 @@ static bool KeepEdge(int type, bool opA,
return false; return false;
} }
static void TagByClassifiedEdge(int bspclass, int *indir, int *outdir) static void TagByClassifiedEdge(SBspUv::Class bspclass, SShell::Class *indir, SShell::Class *outdir)
{ {
switch(bspclass) { switch(bspclass) {
case SBspUv::INSIDE: case SBspUv::Class::INSIDE:
*indir = SShell::INSIDE; *indir = SShell::Class::INSIDE;
*outdir = SShell::INSIDE; *outdir = SShell::Class::INSIDE;
break; break;
case SBspUv::OUTSIDE: case SBspUv::Class::OUTSIDE:
*indir = SShell::OUTSIDE; *indir = SShell::Class::OUTSIDE;
*outdir = SShell::OUTSIDE; *outdir = SShell::Class::OUTSIDE;
break; break;
case SBspUv::EDGE_PARALLEL: case SBspUv::Class::EDGE_PARALLEL:
*indir = SShell::INSIDE; *indir = SShell::Class::INSIDE;
*outdir = SShell::OUTSIDE; *outdir = SShell::Class::OUTSIDE;
break; break;
case SBspUv::EDGE_ANTIPARALLEL: case SBspUv::Class::EDGE_ANTIPARALLEL:
*indir = SShell::OUTSIDE; *indir = SShell::Class::OUTSIDE;
*outdir = SShell::INSIDE; *outdir = SShell::Class::INSIDE;
break; break;
default: default:
dbp("TagByClassifiedEdge: fail!"); dbp("TagByClassifiedEdge: fail!");
*indir = SShell::OUTSIDE; *indir = SShell::Class::OUTSIDE;
*outdir = SShell::OUTSIDE; *outdir = SShell::Class::OUTSIDE;
break; break;
} }
} }
@ -400,7 +400,7 @@ void SSurface::EdgeNormalsWithinSurface(Point2d auv, Point2d buv,
SSurface SSurface::MakeCopyTrimAgainst(SShell *parent, SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
SShell *sha, SShell *shb, SShell *sha, SShell *shb,
SShell *into, SShell *into,
int type) SSurface::CombineAs type)
{ {
bool opA = (parent == sha); bool opA = (parent == sha);
SShell *agnst = opA ? shb : sha; SShell *agnst = opA ? shb : sha;
@ -419,7 +419,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ret.trim.Add(&stn); ret.trim.Add(&stn);
} }
if(type == SShell::AS_DIFFERENCE && !opA) { if(type == SSurface::CombineAs::DIFFERENCE && !opA) {
// The second operand of a Boolean difference gets turned inside out // The second operand of a Boolean difference gets turned inside out
ret.Reverse(); ret.Reverse();
} }
@ -428,7 +428,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
// be changed if we just flipped the surface normal, and we are using // be changed if we just flipped the surface normal, and we are using
// the split curves (not the original curves). // the split curves (not the original curves).
SEdgeList orig = {}; SEdgeList orig = {};
ret.MakeEdgesInto(into, &orig, AS_UV); ret.MakeEdgesInto(into, &orig, MakeAs::UV);
ret.trim.Clear(); ret.trim.Clear();
// which means that we can't necessarily use the old BSP... // which means that we can't necessarily use the old BSP...
SBspUv *origBsp = SBspUv::From(&orig, &ret); SBspUv *origBsp = SBspUv::From(&orig, &ret);
@ -440,7 +440,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
for(ss = agnst->surface.First(); ss; ss = agnst->surface.NextAfter(ss)) { for(ss = agnst->surface.First(); ss; ss = agnst->surface.NextAfter(ss)) {
SCurve *sc; SCurve *sc;
for(sc = into->curve.First(); sc; sc = into->curve.NextAfter(sc)) { for(sc = into->curve.First(); sc; sc = into->curve.NextAfter(sc)) {
if(sc->source != SCurve::FROM_INTERSECTION) continue; if(sc->source != SCurve::Source::INTERSECTION) continue;
if(opA) { if(opA) {
if(sc->surfA.v != h.v || sc->surfB.v != ss->h.v) continue; if(sc->surfA.v != h.v || sc->surfB.v != ss->h.v) continue;
} else { } else {
@ -456,8 +456,8 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ss->ClosestPointTo(a, &(auv.x), &(auv.y)); ss->ClosestPointTo(a, &(auv.x), &(auv.y));
ss->ClosestPointTo(b, &(buv.x), &(buv.y)); ss->ClosestPointTo(b, &(buv.x), &(buv.y));
int c = (ss->bsp) ? ss->bsp->ClassifyEdge(auv, buv, ss) : SBspUv::OUTSIDE; SBspUv::Class c = (ss->bsp) ? ss->bsp->ClassifyEdge(auv, buv, ss) : SBspUv::Class::OUTSIDE;
if(c != SBspUv::OUTSIDE) { if(c != SBspUv::Class::OUTSIDE) {
Vector ta = Vector::From(0, 0, 0); Vector ta = Vector::From(0, 0, 0);
Vector tb = Vector::From(0, 0, 0); Vector tb = Vector::From(0, 0, 0);
ret.ClosestPointTo(a, &(ta.x), &(ta.y)); ret.ClosestPointTo(a, &(ta.x), &(ta.y));
@ -471,7 +471,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
// point opposite to the surface normal. // point opposite to the surface normal.
bool bkwds = true; bool bkwds = true;
if((tn.Cross(b.Minus(a))).Dot(sn) < 0) bkwds = !bkwds; if((tn.Cross(b.Minus(a))).Dot(sn) < 0) bkwds = !bkwds;
if(type == SShell::AS_DIFFERENCE && !opA) bkwds = !bkwds; if(type == SSurface::CombineAs::DIFFERENCE && !opA) bkwds = !bkwds;
if(bkwds) { if(bkwds) {
inter.AddEdge(tb, ta, sc->h.v, 1); inter.AddEdge(tb, ta, sc->h.v, 1);
} else { } else {
@ -525,10 +525,10 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn, ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn,
se->auxA, into, sha, shb); se->auxA, into, sha, shb);
int indir_shell, outdir_shell, indir_orig, outdir_orig; SShell::Class indir_shell, outdir_shell, indir_orig, outdir_orig;
indir_orig = SShell::INSIDE; indir_orig = SShell::Class::INSIDE;
outdir_orig = SShell::OUTSIDE; outdir_orig = SShell::Class::OUTSIDE;
agnst->ClassifyEdge(&indir_shell, &outdir_shell, agnst->ClassifyEdge(&indir_shell, &outdir_shell,
ret.PointAt(auv), ret.PointAt(buv), pt, ret.PointAt(auv), ret.PointAt(buv), pt,
@ -558,9 +558,9 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn, ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn,
se->auxA, into, sha, shb); se->auxA, into, sha, shb);
int indir_shell, outdir_shell, indir_orig, outdir_orig; SShell::Class indir_shell, outdir_shell, indir_orig, outdir_orig;
int c_this = (origBsp) ? origBsp->ClassifyEdge(auv, buv, &ret) : SBspUv::OUTSIDE; SBspUv::Class c_this = (origBsp) ? origBsp->ClassifyEdge(auv, buv, &ret) : SBspUv::Class::OUTSIDE;
TagByClassifiedEdge(c_this, &indir_orig, &outdir_orig); TagByClassifiedEdge(c_this, &indir_orig, &outdir_orig);
agnst->ClassifyEdge(&indir_shell, &outdir_shell, agnst->ClassifyEdge(&indir_shell, &outdir_shell,
@ -602,7 +602,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
return ret; return ret;
} }
void SShell::CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, int type) { void SShell::CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, SSurface::CombineAs type) {
SSurface *ss; SSurface *ss;
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) { for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
SSurface ssn; SSurface ssn;
@ -667,7 +667,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
ab = (i == 0) ? a : b; ab = (i == 0) ? a : b;
for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) { for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) {
cn = SCurve::FromTransformationOf(c, t, q, 1.0); cn = SCurve::FromTransformationOf(c, t, q, 1.0);
cn.source = (i == 0) ? SCurve::FROM_A : SCurve::FROM_B; cn.source = (i == 0) ? SCurve::Source::A : SCurve::Source::B;
// surfA and surfB are wrong now, and we can't fix them until // surfA and surfB are wrong now, and we can't fix them until
// we've assigned IDs to the surfaces. So we'll get that later. // we've assigned IDs to the surfaces. So we'll get that later.
c->newH = curve.AddAndAssignId(&cn); c->newH = curve.AddAndAssignId(&cn);
@ -695,7 +695,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
RewriteSurfaceHandlesForCurves(a, b); RewriteSurfaceHandlesForCurves(a, b);
} }
void SShell::MakeFromBoolean(SShell *a, SShell *b, int type) { void SShell::MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type) {
booleanFailed = false; booleanFailed = false;
a->MakeClassifyingBsps(NULL); a->MakeClassifyingBsps(NULL);
@ -759,12 +759,12 @@ void SShell::MakeClassifyingBsps(SShell *useCurvesFrom) {
void SSurface::MakeClassifyingBsp(SShell *shell, SShell *useCurvesFrom) { void SSurface::MakeClassifyingBsp(SShell *shell, SShell *useCurvesFrom) {
SEdgeList el = {}; SEdgeList el = {};
MakeEdgesInto(shell, &el, AS_UV, useCurvesFrom); MakeEdgesInto(shell, &el, MakeAs::UV, useCurvesFrom);
bsp = SBspUv::From(&el, this); bsp = SBspUv::From(&el, this);
el.Clear(); el.Clear();
edges = {}; edges = {};
MakeEdgesInto(shell, &edges, AS_XYZ, useCurvesFrom); MakeEdgesInto(shell, &edges, MakeAs::XYZ, useCurvesFrom);
} }
SBspUv *SBspUv::Alloc() { SBspUv *SBspUv::Alloc() {
@ -898,7 +898,7 @@ void SBspUv::InsertEdge(Point2d ea, Point2d eb, SSurface *srf) {
return; return;
} }
int SBspUv::ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const { SBspUv::Class SBspUv::ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const {
double dp = ScaledSignedDistanceToLine(p, a, b, srf); double dp = ScaledSignedDistanceToLine(p, a, b, srf);
if(fabs(dp) < LENGTH_EPS) { if(fabs(dp) < LENGTH_EPS) {
@ -908,33 +908,33 @@ int SBspUv::ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const {
if(ScaledDistanceToLine(p, f->a, ba, true, srf) < LENGTH_EPS) { if(ScaledDistanceToLine(p, f->a, ba, true, srf) < LENGTH_EPS) {
if(ScaledDistanceToLine(eb, f->a, ba, false, srf) < LENGTH_EPS){ if(ScaledDistanceToLine(eb, f->a, ba, false, srf) < LENGTH_EPS){
if(ba.Dot(eb.Minus(p)) > 0) { if(ba.Dot(eb.Minus(p)) > 0) {
return EDGE_PARALLEL; return Class::EDGE_PARALLEL;
} else { } else {
return EDGE_ANTIPARALLEL; return Class::EDGE_ANTIPARALLEL;
} }
} else { } else {
return EDGE_OTHER; return Class::EDGE_OTHER;
} }
} }
f = f->more; f = f->more;
} }
// Pick arbitrarily which side to send it down, doesn't matter // Pick arbitrarily which side to send it down, doesn't matter
int c1 = neg ? neg->ClassifyPoint(p, eb, srf) : OUTSIDE; Class c1 = neg ? neg->ClassifyPoint(p, eb, srf) : Class::OUTSIDE;
int c2 = pos ? pos->ClassifyPoint(p, eb, srf) : INSIDE; Class c2 = pos ? pos->ClassifyPoint(p, eb, srf) : Class::INSIDE;
if(c1 != c2) { if(c1 != c2) {
dbp("MISMATCH: %d %d %08x %08x", c1, c2, neg, pos); dbp("MISMATCH: %d %d %08x %08x", c1, c2, neg, pos);
} }
return c1; return c1;
} else if(dp > 0) { } else if(dp > 0) {
return pos ? pos->ClassifyPoint(p, eb, srf) : INSIDE; return pos ? pos->ClassifyPoint(p, eb, srf) : Class::INSIDE;
} else { } else {
return neg ? neg->ClassifyPoint(p, eb, srf) : OUTSIDE; return neg ? neg->ClassifyPoint(p, eb, srf) : Class::OUTSIDE;
} }
} }
int SBspUv::ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const { SBspUv::Class SBspUv::ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const {
int ret = ClassifyPoint((ea.Plus(eb)).ScaledBy(0.5), eb, srf); SBspUv::Class ret = ClassifyPoint((ea.Plus(eb)).ScaledBy(0.5), eb, srf);
if(ret == EDGE_OTHER) { if(ret == Class::EDGE_OTHER) {
// Perhaps the edge is tangent at its midpoint (and we screwed up // Perhaps the edge is tangent at its midpoint (and we screwed up
// somewhere earlier and failed to split it); try a different // somewhere earlier and failed to split it); try a different
// point on the edge. // point on the edge.

View File

@ -752,21 +752,21 @@ void SCurve::Clear() {
} }
SSurface *SCurve::GetSurfaceA(SShell *a, SShell *b) const { SSurface *SCurve::GetSurfaceA(SShell *a, SShell *b) const {
if(source == FROM_A) { if(source == Source::A) {
return a->surface.FindById(surfA); return a->surface.FindById(surfA);
} else if(source == FROM_B) { } else if(source == Source::B) {
return b->surface.FindById(surfA); return b->surface.FindById(surfA);
} else if(source == FROM_INTERSECTION) { } else if(source == Source::INTERSECTION) {
return a->surface.FindById(surfA); return a->surface.FindById(surfA);
} else ssassert(false, "Unexpected curve source"); } else ssassert(false, "Unexpected curve source");
} }
SSurface *SCurve::GetSurfaceB(SShell *a, SShell *b) const { SSurface *SCurve::GetSurfaceB(SShell *a, SShell *b) const {
if(source == FROM_A) { if(source == Source::A) {
return a->surface.FindById(surfB); return a->surface.FindById(surfB);
} else if(source == FROM_B) { } else if(source == Source::B) {
return b->surface.FindById(surfB); return b->surface.FindById(surfB);
} else if(source == FROM_INTERSECTION) { } else if(source == Source::INTERSECTION) {
return b->surface.FindById(surfB); return b->surface.FindById(surfB);
} else ssassert(false, "Unexpected curve source"); } else ssassert(false, "Unexpected curve source");
} }

View File

@ -23,7 +23,7 @@ void SShell::MergeCoincidentSurfaces() {
if(si->degm != 1 || si->degn != 1) continue; if(si->degm != 1 || si->degn != 1) continue;
SEdgeList sel = {}; SEdgeList sel = {};
si->MakeEdgesInto(this, &sel, SSurface::AS_XYZ); si->MakeEdgesInto(this, &sel, SSurface::MakeAs::XYZ);
bool mergedThisTime, merged = false; bool mergedThisTime, merged = false;
do { do {
@ -42,7 +42,7 @@ void SShell::MergeCoincidentSurfaces() {
// the bounding box tests less effective, and possibly things // the bounding box tests less effective, and possibly things
// less robust. // less robust.
SEdgeList tel = {}; SEdgeList tel = {};
sj->MakeEdgesInto(this, &tel, SSurface::AS_XYZ); sj->MakeEdgesInto(this, &tel, SSurface::MakeAs::XYZ);
if(!sel.ContainsEdgeFrom(&tel)) { if(!sel.ContainsEdgeFrom(&tel)) {
tel.Clear(); tel.Clear();
continue; continue;
@ -52,7 +52,7 @@ void SShell::MergeCoincidentSurfaces() {
sj->tag = 1; sj->tag = 1;
merged = true; merged = true;
mergedThisTime = true; mergedThisTime = true;
sj->MakeEdgesInto(this, &sel, SSurface::AS_XYZ); sj->MakeEdgesInto(this, &sel, SSurface::MakeAs::XYZ);
sj->trim.Clear(); sj->trim.Clear();
// All the references to this surface get replaced with the // All the references to this surface get replaced with the

View File

@ -361,8 +361,8 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
// And that it lies inside our trim region // And that it lies inside our trim region
Point2d dummy = { 0, 0 }; Point2d dummy = { 0, 0 };
int c = (bsp) ? bsp->ClassifyPoint(puv, dummy, this) : SBspUv::OUTSIDE; SBspUv::Class c = (bsp) ? bsp->ClassifyPoint(puv, dummy, this) : SBspUv::Class::OUTSIDE;
if(trimmed && c == SBspUv::OUTSIDE) { if(trimmed && c == SBspUv::Class::OUTSIDE) {
continue; continue;
} }
@ -372,7 +372,7 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
si.surfNormal = NormalAt(puv.x, puv.y); si.surfNormal = NormalAt(puv.x, puv.y);
si.pinter = puv; si.pinter = puv;
si.srf = this; si.srf = this;
si.onEdge = (c != SBspUv::INSIDE); si.onEdge = (c != SBspUv::Class::INSIDE);
l->Add(&si); l->Add(&si);
} }
@ -391,7 +391,7 @@ void SShell::AllPointsIntersecting(Vector a, Vector b,
int SShell::ClassifyRegion(Vector edge_n, Vector inter_surf_n, SShell::Class SShell::ClassifyRegion(Vector edge_n, Vector inter_surf_n,
Vector edge_surf_n) const Vector edge_surf_n) const
{ {
double dot = inter_surf_n.DirectionCosineWith(edge_n); double dot = inter_surf_n.DirectionCosineWith(edge_n);
@ -400,14 +400,14 @@ int SShell::ClassifyRegion(Vector edge_n, Vector inter_surf_n,
// are coincident. Test the edge's surface normal // are coincident. Test the edge's surface normal
// to see if it's with same or opposite normals. // to see if it's with same or opposite normals.
if(inter_surf_n.Dot(edge_surf_n) > 0) { if(inter_surf_n.Dot(edge_surf_n) > 0) {
return COINC_SAME; return Class::COINC_SAME;
} else { } else {
return COINC_OPP; return Class::COINC_OPP;
} }
} else if(dot > 0) { } else if(dot > 0) {
return OUTSIDE; return Class::OUTSIDE;
} else { } else {
return INSIDE; return Class::INSIDE;
} }
} }
@ -420,7 +420,7 @@ int SShell::ClassifyRegion(Vector edge_n, Vector inter_surf_n,
// using the closest intersection point. If the ray hits a surface on edge, // using the closest intersection point. If the ray hits a surface on edge,
// then just reattempt in a different random direction. // then just reattempt in a different random direction.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SShell::ClassifyEdge(int *indir, int *outdir, bool SShell::ClassifyEdge(Class *indir, Class *outdir,
Vector ea, Vector eb, Vector ea, Vector eb,
Vector p, Vector p,
Vector edge_n_in, Vector edge_n_out, Vector surf_n) Vector edge_n_in, Vector edge_n_out, Vector surf_n)
@ -474,7 +474,7 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
swap(inter_edge_n[0], inter_edge_n[1]); swap(inter_edge_n[0], inter_edge_n[1]);
} }
int coinc = (surf_n.Dot(inter_surf_n[0])) > 0 ? COINC_SAME : COINC_OPP; Class coinc = (surf_n.Dot(inter_surf_n[0])) > 0 ? Class::COINC_SAME : Class::COINC_OPP;
if(fabs(dotp[0]) < DOTP_TOL && fabs(dotp[1]) < DOTP_TOL) { if(fabs(dotp[0]) < DOTP_TOL && fabs(dotp[1]) < DOTP_TOL) {
// This is actually an edge on face case, just that the face // This is actually an edge on face case, just that the face
@ -484,25 +484,25 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
} else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] > DOTP_TOL) { } else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] > DOTP_TOL) {
if(edge_n_out.Dot(inter_edge_n[0]) > 0) { if(edge_n_out.Dot(inter_edge_n[0]) > 0) {
*indir = coinc; *indir = coinc;
*outdir = OUTSIDE; *outdir = Class::OUTSIDE;
} else { } else {
*indir = INSIDE; *indir = Class::INSIDE;
*outdir = coinc; *outdir = coinc;
} }
} else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] < -DOTP_TOL) { } else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] < -DOTP_TOL) {
if(edge_n_out.Dot(inter_edge_n[0]) > 0) { if(edge_n_out.Dot(inter_edge_n[0]) > 0) {
*indir = coinc; *indir = coinc;
*outdir = INSIDE; *outdir = Class::INSIDE;
} else { } else {
*indir = OUTSIDE; *indir = Class::OUTSIDE;
*outdir = coinc; *outdir = coinc;
} }
} else if(dotp[0] > DOTP_TOL && dotp[1] > DOTP_TOL) { } else if(dotp[0] > DOTP_TOL && dotp[1] > DOTP_TOL) {
*indir = INSIDE; *indir = Class::INSIDE;
*outdir = OUTSIDE; *outdir = Class::OUTSIDE;
} else if(dotp[0] < -DOTP_TOL && dotp[1] < -DOTP_TOL) { } else if(dotp[0] < -DOTP_TOL && dotp[1] < -DOTP_TOL) {
*indir = OUTSIDE; *indir = Class::OUTSIDE;
*outdir = INSIDE; *outdir = Class::INSIDE;
} else { } else {
// Edge is tangent to the shell at shell's edge, so can't be // Edge is tangent to the shell at shell's edge, so can't be
// a boundary of the surface. // a boundary of the surface.
@ -527,8 +527,8 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue; if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
Point2d dummy = { 0, 0 }; Point2d dummy = { 0, 0 };
int c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::OUTSIDE; SBspUv::Class c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::Class::OUTSIDE;
if(c == SBspUv::OUTSIDE) continue; if(c == SBspUv::Class::OUTSIDE) continue;
// Edge-on-face (unless edge-on-edge above superceded) // Edge-on-face (unless edge-on-edge above superceded)
Point2d pin, pout; Point2d pin, pout;
@ -556,8 +556,8 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
p.Minus(ray), p.Plus(ray), &l, false, true, false); p.Minus(ray), p.Plus(ray), &l, false, true, false);
// no intersections means it's outside // no intersections means it's outside
*indir = OUTSIDE; *indir = Class::OUTSIDE;
*outdir = OUTSIDE; *outdir = Class::OUTSIDE;
double dmin = VERY_POSITIVE; double dmin = VERY_POSITIVE;
bool onEdge = false; bool onEdge = false;
edge_inters = 0; edge_inters = 0;
@ -583,11 +583,11 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
// Edge does not lie on surface; either strictly inside // Edge does not lie on surface; either strictly inside
// or strictly outside // or strictly outside
if((si->surfNormal).Dot(ray) > 0) { if((si->surfNormal).Dot(ray) > 0) {
*indir = INSIDE; *indir = Class::INSIDE;
*outdir = INSIDE; *outdir = Class::INSIDE;
} else { } else {
*indir = OUTSIDE; *indir = Class::OUTSIDE;
*outdir = OUTSIDE; *outdir = Class::OUTSIDE;
} }
onEdge = si->onEdge; onEdge = si->onEdge;
} }

View File

@ -204,7 +204,7 @@ bool SSurface::LineEntirelyOutsideBbox(Vector a, Vector b, bool segment) const {
// Generate the piecewise linear approximation of the trim stb, which applies // Generate the piecewise linear approximation of the trim stb, which applies
// to the curve sc. // to the curve sc.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SSurface::MakeTrimEdgesInto(SEdgeList *sel, int flags, void SSurface::MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags,
SCurve *sc, STrimBy *stb) SCurve *sc, STrimBy *stb)
{ {
Vector prev = Vector::From(0, 0, 0); Vector prev = Vector::From(0, 0, 0);
@ -224,7 +224,7 @@ void SSurface::MakeTrimEdgesInto(SEdgeList *sel, int flags,
for(i = first; i != (last + increment); i += increment) { for(i = first; i != (last + increment); i += increment) {
Vector tpt, *pt = &(sc->pts.elem[i].p); Vector tpt, *pt = &(sc->pts.elem[i].p);
if(flags & AS_UV) { if(flags == MakeAs::UV) {
ClosestPointTo(*pt, &u, &v); ClosestPointTo(*pt, &u, &v);
tpt = Vector::From(u, v, 0); tpt = Vector::From(u, v, 0);
} else { } else {
@ -251,7 +251,7 @@ void SSurface::MakeTrimEdgesInto(SEdgeList *sel, int flags,
// the split curves from useCurvesFrom instead of the curves in our own // the split curves from useCurvesFrom instead of the curves in our own
// shell. // shell.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, int flags, void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, MakeAs flags,
SShell *useCurvesFrom) SShell *useCurvesFrom)
{ {
STrimBy *stb; STrimBy *stb;
@ -391,7 +391,7 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
sp = fpt; sp = fpt;
} }
} else { } else {
if(sel) MakeTrimEdgesInto(sel, AS_XYZ, sc, stb); if(sel) MakeTrimEdgesInto(sel, MakeAs::XYZ, sc, stb);
} }
} }
} }
@ -399,7 +399,7 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
void SSurface::TriangulateInto(SShell *shell, SMesh *sm) { void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
SEdgeList el = {}; SEdgeList el = {};
MakeEdgesInto(shell, &el, AS_UV); MakeEdgesInto(shell, &el, MakeAs::UV);
SPolygon poly = {}; SPolygon poly = {};
if(el.AssemblePolygon(&poly, NULL, true)) { if(el.AssemblePolygon(&poly, NULL, true)) {
@ -836,7 +836,7 @@ void SShell::MakeFromTransformationOf(SShell *a,
void SShell::MakeEdgesInto(SEdgeList *sel) { void SShell::MakeEdgesInto(SEdgeList *sel) {
SSurface *s; SSurface *s;
for(s = surface.First(); s; s = surface.NextAfter(s)) { for(s = surface.First(); s; s = surface.NextAfter(s)) {
s->MakeEdgesInto(this, sel, SSurface::AS_XYZ); s->MakeEdgesInto(this, sel, SSurface::MakeAs::XYZ);
} }
} }

View File

@ -10,6 +10,10 @@
#ifndef __SURFACE_H #ifndef __SURFACE_H
#define __SURFACE_H #define __SURFACE_H
#ifdef WIN32
#undef DIFFERENCE
#endif
// Utility functions, Bernstein polynomials of order 1-3 and their derivatives. // Utility functions, Bernstein polynomials of order 1-3 and their derivatives.
double Bernstein(int k, int deg, double t); double Bernstein(int k, int deg, double t);
double BernsteinDerivative(int k, int deg, double t); double BernsteinDerivative(int k, int deg, double t);
@ -28,7 +32,7 @@ public:
SBspUv *more; SBspUv *more;
enum { enum class Class : uint32_t {
INSIDE = 100, INSIDE = 100,
OUTSIDE = 200, OUTSIDE = 200,
EDGE_PARALLEL = 300, EDGE_PARALLEL = 300,
@ -47,8 +51,8 @@ public:
void InsertEdge(Point2d a, Point2d b, SSurface *srf); void InsertEdge(Point2d a, Point2d b, SSurface *srf);
static SBspUv *InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf); static SBspUv *InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf);
int ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const; Class ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const;
int ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const; Class ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const;
double MinimumDistanceToEdge(Point2d p, SSurface *srf) const; double MinimumDistanceToEdge(Point2d p, SSurface *srf) const;
}; };
@ -189,12 +193,12 @@ public:
// therefore must get new hSCurves assigned. For the curves in A and B, // therefore must get new hSCurves assigned. For the curves in A and B,
// we use newH to record their new handle in C. // we use newH to record their new handle in C.
hSCurve newH; hSCurve newH;
enum { enum class Source : uint32_t {
FROM_A = 100, A = 100,
FROM_B = 200, B = 200,
FROM_INTERSECTION = 300 INTERSECTION = 300
}; };
int source; Source source;
bool isExact; bool isExact;
SBezier exact; SBezier exact;
@ -246,6 +250,13 @@ public:
// A rational polynomial surface in Bezier form. // A rational polynomial surface in Bezier form.
class SSurface { class SSurface {
public: public:
enum class CombineAs : uint32_t {
UNION = 10,
DIFFERENCE = 11,
INTERSECT = 12
};
int tag; int tag;
hSSurface h; hSSurface h;
@ -286,7 +297,7 @@ public:
SShell *shell, SShell *sha, SShell *shb); SShell *shell, SShell *sha, SShell *shb);
void FindChainAvoiding(SEdgeList *src, SEdgeList *dest, SPointList *avoid); void FindChainAvoiding(SEdgeList *src, SEdgeList *dest, SPointList *avoid);
SSurface MakeCopyTrimAgainst(SShell *parent, SShell *a, SShell *b, SSurface MakeCopyTrimAgainst(SShell *parent, SShell *a, SShell *b,
SShell *into, int type); SShell *into, SSurface::CombineAs type);
void TrimFromEdgeList(SEdgeList *el, bool asUv); void TrimFromEdgeList(SEdgeList *el, bool asUv);
void IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, void IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
SShell *into); SShell *into);
@ -335,12 +346,12 @@ public:
void TriangulateInto(SShell *shell, SMesh *sm); void TriangulateInto(SShell *shell, SMesh *sm);
// these are intended as bitmasks, even though there's just one now // these are intended as bitmasks, even though there's just one now
enum { enum class MakeAs : uint32_t {
AS_UV = 0x01, UV = 0x01,
AS_XYZ = 0x00 XYZ = 0x00
}; };
void MakeTrimEdgesInto(SEdgeList *sel, int flags, SCurve *sc, STrimBy *stb); void MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags, SCurve *sc, STrimBy *stb);
void MakeEdgesInto(SShell *shell, SEdgeList *sel, int flags, void MakeEdgesInto(SShell *shell, SEdgeList *sel, MakeAs flags,
SShell *useCurvesFrom=NULL); SShell *useCurvesFrom=NULL);
Vector ExactSurfaceTangentAt(Vector p, SSurface *srfA, SSurface *srfB, Vector ExactSurfaceTangentAt(Vector p, SSurface *srfA, SSurface *srfB,
@ -370,14 +381,9 @@ public:
void MakeFromUnionOf(SShell *a, SShell *b); void MakeFromUnionOf(SShell *a, SShell *b);
void MakeFromDifferenceOf(SShell *a, SShell *b); void MakeFromDifferenceOf(SShell *a, SShell *b);
enum { void MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type);
AS_UNION = 10,
AS_DIFFERENCE = 11,
AS_INTERSECT = 12
};
void MakeFromBoolean(SShell *a, SShell *b, int type);
void CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into); void CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into);
void CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, int type); void CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, SSurface::CombineAs type);
void MakeIntersectionCurvesAgainst(SShell *against, SShell *into); void MakeIntersectionCurvesAgainst(SShell *against, SShell *into);
void MakeClassifyingBsps(SShell *useCurvesFrom); void MakeClassifyingBsps(SShell *useCurvesFrom);
void AllPointsIntersecting(Vector a, Vector b, List<SInter> *il, void AllPointsIntersecting(Vector a, Vector b, List<SInter> *il,
@ -390,17 +396,17 @@ public:
// Definitions when classifying regions of a surface; it is either inside, // Definitions when classifying regions of a surface; it is either inside,
// outside, or coincident (with parallel or antiparallel normal) with a // outside, or coincident (with parallel or antiparallel normal) with a
// shell. // shell.
enum { enum class Class : uint32_t {
INSIDE = 100, INSIDE = 100,
OUTSIDE = 200, OUTSIDE = 200,
COINC_SAME = 300, COINC_SAME = 300,
COINC_OPP = 400 COINC_OPP = 400
}; };
static const double DOTP_TOL; static const double DOTP_TOL;
int ClassifyRegion(Vector edge_n, Vector inter_surf_n, Class ClassifyRegion(Vector edge_n, Vector inter_surf_n,
Vector edge_surf_n) const; Vector edge_surf_n) const;
bool ClassifyEdge(int *indir, int *outdir, bool ClassifyEdge(Class *indir, Class *outdir,
Vector ea, Vector eb, Vector ea, Vector eb,
Vector p, Vector edge_n_in, Vector p, Vector edge_n_in,
Vector edge_n_out, Vector surf_n); Vector edge_n_out, Vector surf_n);

View File

@ -100,7 +100,7 @@ void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
ssassert(!(sb->Start()).Equals(sb->Finish()), ssassert(!(sb->Start()).Equals(sb->Finish()),
"Unexpected zero-length edge"); "Unexpected zero-length edge");
split.source = SCurve::FROM_INTERSECTION; split.source = SCurve::Source::INTERSECTION;
into->curve.AddAndAssignId(&split); into->curve.AddAndAssignId(&split);
} }
@ -317,7 +317,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
*srfB = (a == 0) ? b : this; *srfB = (a == 0) ? b : this;
SEdgeList el = {}; SEdgeList el = {};
srfA->MakeEdgesInto(shA, &el, AS_XYZ, NULL); srfA->MakeEdgesInto(shA, &el, MakeAs::XYZ, NULL);
SEdge *se; SEdge *se;
for(se = el.l.First(); se; se = el.l.NextAfter(se)) { for(se = el.l.First(); se; se = el.l.NextAfter(se)) {
@ -365,7 +365,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
sc.surfA = h; sc.surfA = h;
sc.surfB = b->h; sc.surfB = b->h;
sc.isExact = false; sc.isExact = false;
sc.source = SCurve::FROM_INTERSECTION; sc.source = SCurve::Source::INTERSECTION;
Vector start = spl.l.elem[0].p, Vector start = spl.l.elem[0].p,
startv = spl.l.elem[0].auxv; startv = spl.l.elem[0].auxv;
@ -502,7 +502,7 @@ void SShell::MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
SSurface *ss; SSurface *ss;
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) { for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
if(proto->CoincidentWith(ss, sameNormal)) { if(proto->CoincidentWith(ss, sameNormal)) {
ss->MakeEdgesInto(this, el, SSurface::AS_XYZ, useCurvesFrom); ss->MakeEdgesInto(this, el, SSurface::MakeAs::XYZ, useCurvesFrom);
} }
} }

View File

@ -278,8 +278,8 @@ void SContour::ClipEarInto(SMesh *m, int bp, double scaledEps) {
// By deleting the point at bp, we may change the ear-ness of the points // By deleting the point at bp, we may change the ear-ness of the points
// on either side. // on either side.
l.elem[ap].ear = SPoint::UNKNOWN; l.elem[ap].ear = EarType::UNKNOWN;
l.elem[cp].ear = SPoint::UNKNOWN; l.elem[cp].ear = EarType::UNKNOWN;
l.ClearTags(); l.ClearTags();
l.elem[bp].tag = 1; l.elem[bp].tag = 1;
@ -307,16 +307,16 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
// Now calculate the ear-ness of each vertex // Now calculate the ear-ness of each vertex
for(i = 0; i < l.n; i++) { for(i = 0; i < l.n; i++) {
(l.elem[i]).ear = IsEar(i, scaledEps) ? SPoint::EAR : SPoint::NOT_EAR; (l.elem[i]).ear = IsEar(i, scaledEps) ? EarType::EAR : EarType::NOT_EAR;
} }
bool toggle = false; bool toggle = false;
while(l.n > 3) { while(l.n > 3) {
// Some points may have changed ear-ness, so recalculate // Some points may have changed ear-ness, so recalculate
for(i = 0; i < l.n; i++) { for(i = 0; i < l.n; i++) {
if(l.elem[i].ear == SPoint::UNKNOWN) { if(l.elem[i].ear == EarType::UNKNOWN) {
(l.elem[i]).ear = IsEar(i, scaledEps) ? (l.elem[i]).ear = IsEar(i, scaledEps) ?
SPoint::EAR : SPoint::NOT_EAR; EarType::EAR : EarType::NOT_EAR;
} }
} }
@ -328,7 +328,7 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
int offset = toggle ? -1 : 0; int offset = toggle ? -1 : 0;
for(i = 0; i < l.n; i++) { for(i = 0; i < l.n; i++) {
int ear = WRAP(i+offset, l.n); int ear = WRAP(i+offset, l.n);
if(l.elem[ear].ear == SPoint::EAR) { if(l.elem[ear].ear == EarType::EAR) {
if(srf->degm == 1 && srf->degn == 1) { if(srf->degm == 1 && srf->degn == 1) {
// This is a plane; any ear is a good ear. // This is a plane; any ear is a good ear.
bestEar = ear; bestEar = ear;

View File

@ -87,17 +87,17 @@ void Style::FillDefaultStyle(Style *s, const Default *d) {
if(d == NULL) d = &Defaults[0]; if(d == NULL) d = &Defaults[0];
s->color = CnfThawColor(d->color, CnfColor(d->cnfPrefix)); s->color = CnfThawColor(d->color, CnfColor(d->cnfPrefix));
s->width = CnfThawFloat((float)(d->width), CnfWidth(d->cnfPrefix)); s->width = CnfThawFloat((float)(d->width), CnfWidth(d->cnfPrefix));
s->widthAs = UNITS_AS_PIXELS; s->widthAs = UnitsAs::PIXELS;
s->textHeight = CnfThawFloat(DEFAULT_TEXT_HEIGHT, CnfTextHeight(d->cnfPrefix)); s->textHeight = CnfThawFloat(DEFAULT_TEXT_HEIGHT, CnfTextHeight(d->cnfPrefix));
s->textHeightAs = UNITS_AS_PIXELS; s->textHeightAs = UnitsAs::PIXELS;
s->textOrigin = 0; s->textOrigin = TextOrigin::NONE;
s->textAngle = 0; s->textAngle = 0;
s->visible = true; s->visible = true;
s->exportable = true; s->exportable = true;
s->filled = false; s->filled = false;
s->fillColor = RGBf(0.3, 0.3, 0.3); s->fillColor = RGBf(0.3, 0.3, 0.3);
s->stippleType = (d->h.v == Style::HIDDEN_EDGE) ? Style::STIPPLE_DASH s->stippleType = (d->h.v == Style::HIDDEN_EDGE) ? StipplePattern::DASH
: Style::STIPPLE_CONTINUOUS; : StipplePattern::CONTINUOUS;
s->stippleScale = 15.0; s->stippleScale = 15.0;
s->zIndex = d->zIndex; s->zIndex = d->zIndex;
} }
@ -168,7 +168,7 @@ void Style::AssignSelectionToStyle(uint32_t v) {
SS.ScheduleGenerateAll(); SS.ScheduleGenerateAll();
// And show that style's info screen in the text window. // And show that style's info screen in the text window.
SS.TW.GoToScreen(TextWindow::SCREEN_STYLE_INFO); SS.TW.GoToScreen(TextWindow::Screen::STYLE_INFO);
SS.TW.shown.style.v = v; SS.TW.shown.style.v = v;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
@ -252,9 +252,9 @@ RgbaColor Style::FillColor(hStyle h, bool forExport) {
float Style::Width(hStyle h) { float Style::Width(hStyle h) {
double r = 1.0; double r = 1.0;
Style *s = Get(h); Style *s = Get(h);
if(s->widthAs == UNITS_AS_MM) { if(s->widthAs == UnitsAs::MM) {
r = s->width * SS.GW.scale; r = s->width * SS.GW.scale;
} else if(s->widthAs == UNITS_AS_PIXELS) { } else if(s->widthAs == UnitsAs::PIXELS) {
r = s->width; r = s->width;
} }
// This returns a float because ssglLineWidth expects a float, avoid casts. // This returns a float because ssglLineWidth expects a float, avoid casts.
@ -274,7 +274,7 @@ double Style::WidthMm(int hs) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
double Style::TextHeight(hStyle hs) { double Style::TextHeight(hStyle hs) {
Style *s = Get(hs); Style *s = Get(hs);
if(s->textHeightAs == UNITS_AS_MM) { if(s->textHeightAs == UnitsAs::MM) {
return s->textHeight * SS.GW.scale; return s->textHeight * SS.GW.scale;
} else /* s->textHeightAs == UNITS_AS_PIXELS */ { } else /* s->textHeightAs == UNITS_AS_PIXELS */ {
return s->textHeight; return s->textHeight;
@ -321,16 +321,16 @@ hStyle Style::ForEntity(hEntity he) {
return hs; return hs;
} }
int Style::PatternType(hStyle hs) { StipplePattern Style::PatternType(hStyle hs) {
Style *s = Get(hs); Style *s = Get(hs);
return s->stippleType; return s->stippleType;
} }
double Style::StippleScaleMm(hStyle hs) { double Style::StippleScaleMm(hStyle hs) {
Style *s = Get(hs); Style *s = Get(hs);
if(s->widthAs == UNITS_AS_MM) { if(s->widthAs == UnitsAs::MM) {
return s->stippleScale; return s->stippleScale;
} else if(s->widthAs == UNITS_AS_PIXELS) { } else if(s->widthAs == UnitsAs::PIXELS) {
return s->stippleScale / SS.GW.scale; return s->stippleScale / SS.GW.scale;
} }
return 1.0; return 1.0;
@ -346,16 +346,16 @@ std::string Style::DescriptionString() const {
void TextWindow::ScreenShowListOfStyles(int link, uint32_t v) { void TextWindow::ScreenShowListOfStyles(int link, uint32_t v) {
SS.TW.GoToScreen(SCREEN_LIST_OF_STYLES); SS.TW.GoToScreen(Screen::LIST_OF_STYLES);
} }
void TextWindow::ScreenShowStyleInfo(int link, uint32_t v) { void TextWindow::ScreenShowStyleInfo(int link, uint32_t v) {
SS.TW.GoToScreen(SCREEN_STYLE_INFO); SS.TW.GoToScreen(Screen::STYLE_INFO);
SS.TW.shown.style.v = v; SS.TW.shown.style.v = v;
} }
void TextWindow::ScreenLoadFactoryDefaultStyles(int link, uint32_t v) { void TextWindow::ScreenLoadFactoryDefaultStyles(int link, uint32_t v) {
Style::LoadFactoryDefaults(); Style::LoadFactoryDefaults();
SS.TW.GoToScreen(SCREEN_LIST_OF_STYLES); SS.TW.GoToScreen(Screen::LIST_OF_STYLES);
} }
void TextWindow::ScreenCreateCustomStyle(int link, uint32_t v) { void TextWindow::ScreenCreateCustomStyle(int link, uint32_t v) {
@ -365,7 +365,7 @@ void TextWindow::ScreenCreateCustomStyle(int link, uint32_t v) {
void TextWindow::ScreenChangeBackgroundColor(int link, uint32_t v) { void TextWindow::ScreenChangeBackgroundColor(int link, uint32_t v) {
RgbaColor rgb = SS.backgroundColor; RgbaColor rgb = SS.backgroundColor;
SS.TW.ShowEditControlWithColorPicker(3, rgb); SS.TW.ShowEditControlWithColorPicker(3, rgb);
SS.TW.edit.meaning = EDIT_BACKGROUND_COLOR; SS.TW.edit.meaning = Edit::BACKGROUND_COLOR;
} }
static int RoundUpToPowerOfTwo(int v) static int RoundUpToPowerOfTwo(int v)
@ -398,7 +398,7 @@ void TextWindow::ScreenBackgroundImage(int link, uint32_t v) {
} }
void TextWindow::ScreenChangeBackgroundImageScale(int link, uint32_t v) { void TextWindow::ScreenChangeBackgroundImageScale(int link, uint32_t v) {
SS.TW.edit.meaning = EDIT_BACKGROUND_IMG_SCALE; SS.TW.edit.meaning = Edit::BACKGROUND_IMG_SCALE;
SS.TW.ShowEditControl(10, ssprintf("%.3f", SS.bgImage.scale * SS.MmPerUnit())); SS.TW.ShowEditControl(10, ssprintf("%.3f", SS.bgImage.scale * SS.MmPerUnit()));
} }
@ -459,7 +459,7 @@ void TextWindow::ScreenChangeStyleName(int link, uint32_t v) {
Style *s = Style::Get(hs); Style *s = Style::Get(hs);
SS.TW.ShowEditControl(12, s->name); SS.TW.ShowEditControl(12, s->name);
SS.TW.edit.style = hs; SS.TW.edit.style = hs;
SS.TW.edit.meaning = EDIT_STYLE_NAME; SS.TW.edit.meaning = Edit::STYLE_NAME;
} }
void TextWindow::ScreenDeleteStyle(int link, uint32_t v) { void TextWindow::ScreenDeleteStyle(int link, uint32_t v) {
@ -471,34 +471,36 @@ void TextWindow::ScreenDeleteStyle(int link, uint32_t v) {
// And it will get recreated automatically if something is still using // And it will get recreated automatically if something is still using
// the style, so no need to do anything else. // the style, so no need to do anything else.
} }
SS.TW.GoToScreen(SCREEN_LIST_OF_STYLES); SS.TW.GoToScreen(Screen::LIST_OF_STYLES);
InvalidateGraphics(); InvalidateGraphics();
} }
void TextWindow::ScreenChangeStylePatternType(int link, uint32_t v) { void TextWindow::ScreenChangeStylePatternType(int link, uint32_t v) {
hStyle hs = { v }; hStyle hs = { v };
Style *s = Style::Get(hs); Style *s = Style::Get(hs);
s->stippleType = link - 1; s->stippleType = (StipplePattern)(link - 1);
} }
void TextWindow::ScreenChangeStyleMetric(int link, uint32_t v) { void TextWindow::ScreenChangeStyleMetric(int link, uint32_t v) {
hStyle hs = { v }; hStyle hs = { v };
Style *s = Style::Get(hs); Style *s = Style::Get(hs);
double val; double val;
int units, meaning, col; Style::UnitsAs units;
Edit meaning;
int col;
switch(link) { switch(link) {
case 't': case 't':
val = s->textHeight; val = s->textHeight;
units = s->textHeightAs; units = s->textHeightAs;
col = 10; col = 10;
meaning = EDIT_STYLE_TEXT_HEIGHT; meaning = Edit::STYLE_TEXT_HEIGHT;
break; break;
case 's': case 's':
val = s->stippleScale; val = s->stippleScale;
units = s->widthAs; units = s->widthAs;
col = 17; col = 17;
meaning = EDIT_STYLE_STIPPLE_PERIOD; meaning = Edit::STYLE_STIPPLE_PERIOD;
break; break;
case 'w': case 'w':
@ -506,14 +508,14 @@ void TextWindow::ScreenChangeStyleMetric(int link, uint32_t v) {
val = s->width; val = s->width;
units = s->widthAs; units = s->widthAs;
col = 9; col = 9;
meaning = EDIT_STYLE_WIDTH; meaning = Edit::STYLE_WIDTH;
break; break;
default: ssassert(false, "Unexpected link"); default: ssassert(false, "Unexpected link");
} }
std::string edit_value; std::string edit_value;
if(units == Style::UNITS_AS_PIXELS) { if(units == Style::UnitsAs::PIXELS) {
edit_value = ssprintf("%.2f", val); edit_value = ssprintf("%.2f", val);
} else { } else {
edit_value = SS.MmToString(val); edit_value = SS.MmToString(val);
@ -528,20 +530,20 @@ void TextWindow::ScreenChangeStyleTextAngle(int link, uint32_t v) {
Style *s = Style::Get(hs); Style *s = Style::Get(hs);
SS.TW.ShowEditControl(9, ssprintf("%.2f", s->textAngle)); SS.TW.ShowEditControl(9, ssprintf("%.2f", s->textAngle));
SS.TW.edit.style = hs; SS.TW.edit.style = hs;
SS.TW.edit.meaning = EDIT_STYLE_TEXT_ANGLE; SS.TW.edit.meaning = Edit::STYLE_TEXT_ANGLE;
} }
void TextWindow::ScreenChangeStyleColor(int link, uint32_t v) { void TextWindow::ScreenChangeStyleColor(int link, uint32_t v) {
hStyle hs = { v }; hStyle hs = { v };
Style *s = Style::Get(hs); Style *s = Style::Get(hs);
// Same function used for stroke and fill colors // Same function used for stroke and fill colors
int em; Edit em;
RgbaColor rgb; RgbaColor rgb;
if(link == 's') { if(link == 's') {
em = EDIT_STYLE_COLOR; em = Edit::STYLE_COLOR;
rgb = s->color; rgb = s->color;
} else if(link == 'f') { } else if(link == 'f') {
em = EDIT_STYLE_FILL_COLOR; em = Edit::STYLE_FILL_COLOR;
rgb = s->fillColor; rgb = s->fillColor;
} else ssassert(false, "Unexpected link"); } else ssassert(false, "Unexpected link");
SS.TW.ShowEditControlWithColorPicker(13, rgb); SS.TW.ShowEditControlWithColorPicker(13, rgb);
@ -556,15 +558,15 @@ void TextWindow::ScreenChangeStyleYesNo(int link, uint32_t v) {
switch(link) { switch(link) {
// Units for the width // Units for the width
case 'w': case 'w':
if(s->widthAs != Style::UNITS_AS_MM) { if(s->widthAs != Style::UnitsAs::MM) {
s->widthAs = Style::UNITS_AS_MM; s->widthAs = Style::UnitsAs::MM;
s->width /= SS.GW.scale; s->width /= SS.GW.scale;
s->stippleScale /= SS.GW.scale; s->stippleScale /= SS.GW.scale;
} }
break; break;
case 'W': case 'W':
if(s->widthAs != Style::UNITS_AS_PIXELS) { if(s->widthAs != Style::UnitsAs::PIXELS) {
s->widthAs = Style::UNITS_AS_PIXELS; s->widthAs = Style::UnitsAs::PIXELS;
s->width *= SS.GW.scale; s->width *= SS.GW.scale;
s->stippleScale *= SS.GW.scale; s->stippleScale *= SS.GW.scale;
} }
@ -572,15 +574,15 @@ void TextWindow::ScreenChangeStyleYesNo(int link, uint32_t v) {
// Units for the height // Units for the height
case 'g': case 'g':
if(s->textHeightAs != Style::UNITS_AS_MM) { if(s->textHeightAs != Style::UnitsAs::MM) {
s->textHeightAs = Style::UNITS_AS_MM; s->textHeightAs = Style::UnitsAs::MM;
s->textHeight /= SS.GW.scale; s->textHeight /= SS.GW.scale;
} }
break; break;
case 'G': case 'G':
if(s->textHeightAs != Style::UNITS_AS_PIXELS) { if(s->textHeightAs != Style::UnitsAs::PIXELS) {
s->textHeightAs = Style::UNITS_AS_PIXELS; s->textHeightAs = Style::UnitsAs::PIXELS;
s->textHeight *= SS.GW.scale; s->textHeight *= SS.GW.scale;
} }
break; break;
@ -599,30 +601,30 @@ void TextWindow::ScreenChangeStyleYesNo(int link, uint32_t v) {
// Horizontal text alignment // Horizontal text alignment
case 'L': case 'L':
s->textOrigin |= Style::ORIGIN_LEFT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::LEFT);
s->textOrigin &= ~Style::ORIGIN_RIGHT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::RIGHT);
break; break;
case 'H': case 'H':
s->textOrigin &= ~Style::ORIGIN_LEFT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::LEFT);
s->textOrigin &= ~Style::ORIGIN_RIGHT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::RIGHT);
break; break;
case 'R': case 'R':
s->textOrigin &= ~Style::ORIGIN_LEFT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::LEFT);
s->textOrigin |= Style::ORIGIN_RIGHT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::RIGHT);
break; break;
// Vertical text alignment // Vertical text alignment
case 'B': case 'B':
s->textOrigin |= Style::ORIGIN_BOT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::BOT);
s->textOrigin &= ~Style::ORIGIN_TOP; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::TOP);
break; break;
case 'V': case 'V':
s->textOrigin &= ~Style::ORIGIN_BOT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::BOT);
s->textOrigin &= ~Style::ORIGIN_TOP; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::TOP);
break; break;
case 'T': case 'T':
s->textOrigin &= ~Style::ORIGIN_BOT; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::BOT);
s->textOrigin |= Style::ORIGIN_TOP; s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::TOP);
break; break;
} }
InvalidateGraphics(); InvalidateGraphics();
@ -631,47 +633,47 @@ void TextWindow::ScreenChangeStyleYesNo(int link, uint32_t v) {
bool TextWindow::EditControlDoneForStyles(const char *str) { bool TextWindow::EditControlDoneForStyles(const char *str) {
Style *s; Style *s;
switch(edit.meaning) { switch(edit.meaning) {
case EDIT_STYLE_STIPPLE_PERIOD: case Edit::STYLE_STIPPLE_PERIOD:
case EDIT_STYLE_TEXT_HEIGHT: case Edit::STYLE_TEXT_HEIGHT:
case EDIT_STYLE_WIDTH: { case Edit::STYLE_WIDTH: {
SS.UndoRemember(); SS.UndoRemember();
s = Style::Get(edit.style); s = Style::Get(edit.style);
double v; double v;
int units = (edit.meaning == EDIT_STYLE_TEXT_HEIGHT) ? Style::UnitsAs units = (edit.meaning == Edit::STYLE_TEXT_HEIGHT) ?
s->textHeightAs : s->widthAs; s->textHeightAs : s->widthAs;
if(units == Style::UNITS_AS_MM) { if(units == Style::UnitsAs::MM) {
v = SS.StringToMm(str); v = SS.StringToMm(str);
} else { } else {
v = atof(str); v = atof(str);
} }
v = max(0.0, v); v = max(0.0, v);
if(edit.meaning == EDIT_STYLE_TEXT_HEIGHT) { if(edit.meaning == Edit::STYLE_TEXT_HEIGHT) {
s->textHeight = v; s->textHeight = v;
} else if(edit.meaning == EDIT_STYLE_STIPPLE_PERIOD) { } else if(edit.meaning == Edit::STYLE_STIPPLE_PERIOD) {
s->stippleScale = v; s->stippleScale = v;
} else { } else {
s->width = v; s->width = v;
} }
break; break;
} }
case EDIT_STYLE_TEXT_ANGLE: case Edit::STYLE_TEXT_ANGLE:
SS.UndoRemember(); SS.UndoRemember();
s = Style::Get(edit.style); s = Style::Get(edit.style);
s->textAngle = WRAP_SYMMETRIC(atof(str), 360); s->textAngle = WRAP_SYMMETRIC(atof(str), 360);
break; break;
case EDIT_BACKGROUND_COLOR: case Edit::BACKGROUND_COLOR:
case EDIT_STYLE_FILL_COLOR: case Edit::STYLE_FILL_COLOR:
case EDIT_STYLE_COLOR: { case Edit::STYLE_COLOR: {
Vector rgb; Vector rgb;
if(sscanf(str, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { if(sscanf(str, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) {
rgb = rgb.ClampWithin(0, 1); rgb = rgb.ClampWithin(0, 1);
if(edit.meaning == EDIT_STYLE_COLOR) { if(edit.meaning == Edit::STYLE_COLOR) {
SS.UndoRemember(); SS.UndoRemember();
s = Style::Get(edit.style); s = Style::Get(edit.style);
s->color = RGBf(rgb.x, rgb.y, rgb.z); s->color = RGBf(rgb.x, rgb.y, rgb.z);
} else if(edit.meaning == EDIT_STYLE_FILL_COLOR) { } else if(edit.meaning == Edit::STYLE_FILL_COLOR) {
SS.UndoRemember(); SS.UndoRemember();
s = Style::Get(edit.style); s = Style::Get(edit.style);
s->fillColor = RGBf(rgb.x, rgb.y, rgb.z); s->fillColor = RGBf(rgb.x, rgb.y, rgb.z);
@ -683,7 +685,7 @@ bool TextWindow::EditControlDoneForStyles(const char *str) {
} }
break; break;
} }
case EDIT_STYLE_NAME: case Edit::STYLE_NAME:
if(!*str) { if(!*str) {
Error("Style name cannot be empty"); Error("Style name cannot be empty");
} else { } else {
@ -693,7 +695,7 @@ bool TextWindow::EditControlDoneForStyles(const char *str) {
} }
break; break;
case EDIT_BACKGROUND_IMG_SCALE: { case Edit::BACKGROUND_IMG_SCALE: {
Expr *e = Expr::From(str, true); Expr *e = Expr::From(str, true);
if(e) { if(e) {
double ev = e->Eval(); double ev = e->Eval();
@ -731,7 +733,7 @@ void TextWindow::ShowStyleInfo() {
s->h.v, ScreenChangeStyleColor); s->h.v, ScreenChangeStyleColor);
// The line width, and its units // The line width, and its units
if(s->widthAs == Style::UNITS_AS_PIXELS) { if(s->widthAs == Style::UnitsAs::PIXELS) {
Printf(false, " %Ftwidth%E %@ %D%f%Lp%Fl[change]%E", Printf(false, " %Ftwidth%E %@ %D%f%Lp%Fl[change]%E",
s->width, s->width,
s->h.v, &ScreenChangeStyleMetric, s->h.v, &ScreenChangeStyleMetric,
@ -744,7 +746,7 @@ void TextWindow::ShowStyleInfo() {
} }
if(s->h.v >= Style::FIRST_CUSTOM) { if(s->h.v >= Style::FIRST_CUSTOM) {
if(s->widthAs == Style::UNITS_AS_PIXELS) { if(s->widthAs == Style::UnitsAs::PIXELS) {
Printf(false, "%Ba %Ftstipple width%E %@ %D%f%Lp%Fl[change]%E", Printf(false, "%Ba %Ftstipple width%E %@ %D%f%Lp%Fl[change]%E",
s->stippleScale, s->stippleScale,
s->h.v, &ScreenChangeStyleMetric, 's'); s->h.v, &ScreenChangeStyleMetric, 's');
@ -755,7 +757,7 @@ void TextWindow::ShowStyleInfo() {
} }
} }
bool widthpx = (s->widthAs == Style::UNITS_AS_PIXELS); bool widthpx = (s->widthAs == Style::UnitsAs::PIXELS);
if(s->h.v < Style::FIRST_CUSTOM) { if(s->h.v < Style::FIRST_CUSTOM) {
Printf(false," %Ftin units of %Fdpixels%E"); Printf(false," %Ftin units of %Fdpixels%E");
} else { } else {
@ -771,7 +773,7 @@ void TextWindow::ShowStyleInfo() {
Printf(false,"%Ba %Ftstipple type:%E"); Printf(false,"%Ba %Ftstipple type:%E");
const size_t patternCount = Style::LAST_STIPPLE + 1; const size_t patternCount = (size_t)StipplePattern::LAST + 1;
const char *patternsSource[patternCount] = { const char *patternsSource[patternCount] = {
"___________", "___________",
"- - - - - -", "- - - - - -",
@ -784,7 +786,7 @@ void TextWindow::ShowStyleInfo() {
}; };
std::string patterns[patternCount]; std::string patterns[patternCount];
for(int i = 0; i <= Style::LAST_STIPPLE; i++) { for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) {
const char *str = patternsSource[i]; const char *str = patternsSource[i];
do { do {
switch(*str) { switch(*str) {
@ -798,8 +800,8 @@ void TextWindow::ShowStyleInfo() {
} while(*(++str)); } while(*(++str));
} }
for(int i = 0; i <= Style::LAST_STIPPLE; i++) { for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) {
const char *radio = s->stippleType == i ? RADIO_TRUE : RADIO_FALSE; const char *radio = s->stippleType == (StipplePattern)i ? RADIO_TRUE : RADIO_FALSE;
Printf(false, "%Bp %D%f%Lp%s %s%E", Printf(false, "%Bp %D%f%Lp%s %s%E",
(i % 2 == 0) ? 'd' : 'a', (i % 2 == 0) ? 'd' : 'a',
s->h.v, &ScreenChangeStylePatternType, s->h.v, &ScreenChangeStylePatternType,
@ -826,7 +828,7 @@ void TextWindow::ShowStyleInfo() {
Printf(false, ""); Printf(false, "");
Printf(false, "%Ft text style%E"); Printf(false, "%Ft text style%E");
if(s->textHeightAs == Style::UNITS_AS_PIXELS) { if(s->textHeightAs == Style::UnitsAs::PIXELS) {
Printf(false, "%Ba %Ftheight %E%@ %D%f%Lt%Fl%s%E", Printf(false, "%Ba %Ftheight %E%@ %D%f%Lt%Fl%s%E",
s->textHeight, s->textHeight,
s->h.v, &ScreenChangeStyleMetric, s->h.v, &ScreenChangeStyleMetric,
@ -838,7 +840,7 @@ void TextWindow::ShowStyleInfo() {
"[change]"); "[change]");
} }
bool textHeightpx = (s->textHeightAs == Style::UNITS_AS_PIXELS); bool textHeightpx = (s->textHeightAs == Style::UnitsAs::PIXELS);
if(s->h.v < Style::FIRST_CUSTOM) { if(s->h.v < Style::FIRST_CUSTOM) {
Printf(false,"%Bd %Ftin units of %Fdpixels"); Printf(false,"%Bd %Ftin units of %Fdpixels");
} else { } else {
@ -860,29 +862,29 @@ void TextWindow::ShowStyleInfo() {
Printf(false, ""); Printf(false, "");
Printf(false, "%Ft text comment alignment%E"); Printf(false, "%Ft text comment alignment%E");
bool neither; bool neither;
neither = !(s->textOrigin & (Style::ORIGIN_LEFT | Style::ORIGIN_RIGHT)); neither = !((uint32_t)s->textOrigin & ((uint32_t)Style::TextOrigin::LEFT | (uint32_t)Style::TextOrigin::RIGHT));
Printf(false, "%Ba " Printf(false, "%Ba "
"%D%f%LL%s left%E " "%D%f%LL%s left%E "
"%D%f%LH%s center%E " "%D%f%LH%s center%E "
"%D%f%LR%s right%E ", "%D%f%LR%s right%E ",
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
(s->textOrigin & Style::ORIGIN_LEFT) ? RADIO_TRUE : RADIO_FALSE, ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::LEFT) ? RADIO_TRUE : RADIO_FALSE,
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
neither ? RADIO_TRUE : RADIO_FALSE, neither ? RADIO_TRUE : RADIO_FALSE,
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
(s->textOrigin & Style::ORIGIN_RIGHT) ? RADIO_TRUE : RADIO_FALSE); ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::RIGHT) ? RADIO_TRUE : RADIO_FALSE);
neither = !(s->textOrigin & (Style::ORIGIN_BOT | Style::ORIGIN_TOP)); neither = !((uint32_t)s->textOrigin & ((uint32_t)Style::TextOrigin::BOT | (uint32_t)Style::TextOrigin::TOP));
Printf(false, "%Bd " Printf(false, "%Bd "
"%D%f%LB%s bottom%E " "%D%f%LB%s bottom%E "
"%D%f%LV%s center%E " "%D%f%LV%s center%E "
"%D%f%LT%s top%E ", "%D%f%LT%s top%E ",
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
(s->textOrigin & Style::ORIGIN_BOT) ? RADIO_TRUE : RADIO_FALSE, ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::BOT) ? RADIO_TRUE : RADIO_FALSE,
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
neither ? RADIO_TRUE : RADIO_FALSE, neither ? RADIO_TRUE : RADIO_FALSE,
s->h.v, &ScreenChangeStyleYesNo, s->h.v, &ScreenChangeStyleYesNo,
(s->textOrigin & Style::ORIGIN_TOP) ? RADIO_TRUE : RADIO_FALSE); ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::TOP) ? RADIO_TRUE : RADIO_FALSE);
} }
if(s->h.v >= Style::FIRST_CUSTOM) { if(s->h.v >= Style::FIRST_CUSTOM) {

View File

@ -90,9 +90,9 @@ void System::SolveBySubstitution() {
Equation *teq = &(eq.elem[i]); Equation *teq = &(eq.elem[i]);
Expr *tex = teq->e; Expr *tex = teq->e;
if(tex->op == Expr::MINUS && if(tex->op == Expr::Op::MINUS &&
tex->a->op == Expr::PARAM && tex->a->op == Expr::Op::PARAM &&
tex->b->op == Expr::PARAM) tex->b->op == Expr::Op::PARAM)
{ {
hParam a = tex->a->parh; hParam a = tex->a->parh;
hParam b = tex->b->parh; hParam b = tex->b->parh;
@ -331,7 +331,7 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
if(c->group.v != g->h.v) continue; if(c->group.v != g->h.v) continue;
if(c->h.v == hc.v) continue; if(c->h.v == hc.v) continue;
if(c->HasLabel() && c->type != Constraint::COMMENT && if(c->HasLabel() && c->type != Constraint::Type::COMMENT &&
g->allDimsReference) g->allDimsReference)
{ {
// When all dimensions are reference, we adjust them to display // When all dimensions are reference, we adjust them to display
@ -339,7 +339,7 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
c->ModifyToSatisfy(); c->ModifyToSatisfy();
continue; continue;
} }
if(g->relaxConstraints && c->type != Constraint::POINTS_COINCIDENT) { if(g->relaxConstraints && c->type != Constraint::Type::POINTS_COINCIDENT) {
// When the constraints are relaxed, we keep only the point- // When the constraints are relaxed, we keep only the point-
// coincident constraints, and the constraints generated by // coincident constraints, and the constraints generated by
// the entities and groups. // the entities and groups.
@ -366,8 +366,8 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
for(i = 0; i < SK.constraint.n; i++) { for(i = 0; i < SK.constraint.n; i++) {
ConstraintBase *c = &(SK.constraint.elem[i]); ConstraintBase *c = &(SK.constraint.elem[i]);
if(c->group.v != g->h.v) continue; if(c->group.v != g->h.v) continue;
if((c->type == Constraint::POINTS_COINCIDENT && a == 0) || if((c->type == Constraint::Type::POINTS_COINCIDENT && a == 0) ||
(c->type != Constraint::POINTS_COINCIDENT && a == 1)) (c->type != Constraint::Type::POINTS_COINCIDENT && a == 1))
{ {
// Do the constraints in two passes: first everything but // Do the constraints in two passes: first everything but
// the point-coincident constraints, then only those // the point-coincident constraints, then only those
@ -396,7 +396,7 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
} }
} }
int System::Solve(Group *g, int *dof, List<hConstraint> *bad, SolveResult System::Solve(Group *g, int *dof, List<hConstraint> *bad,
bool andFindBad, bool andFindFree) bool andFindBad, bool andFindFree)
{ {
WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g); WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g);
@ -449,7 +449,7 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
// Now write the Jacobian for what's left, and do a rank test; that // Now write the Jacobian for what's left, and do a rank test; that
// tells us if the system is inconsistently constrained. // tells us if the system is inconsistently constrained.
if(!WriteJacobian(0)) { if(!WriteJacobian(0)) {
return System::TOO_MANY_UNKNOWNS; return SolveResult::TOO_MANY_UNKNOWNS;
} }
rankOk = TestRank(); rankOk = TestRank();
@ -463,7 +463,7 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
if(!rankOk) { if(!rankOk) {
if(!g->allowRedundant) { if(!g->allowRedundant) {
if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad); if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad);
return System::REDUNDANT_OKAY; return SolveResult::REDUNDANT_OKAY;
} }
} }
@ -508,7 +508,7 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
pp->known = true; pp->known = true;
pp->free = p->free; pp->free = p->free;
} }
return rankOk ? System::SOLVED_OKAY : System::REDUNDANT_OKAY; return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY;
didnt_converge: didnt_converge:
SK.constraint.ClearTags(); SK.constraint.ClearTags();
@ -529,7 +529,7 @@ didnt_converge:
} }
} }
return rankOk ? System::DIDNT_CONVERGE : System::REDUNDANT_DIDNT_CONVERGE; return rankOk ? SolveResult::DIDNT_CONVERGE : SolveResult::REDUNDANT_DIDNT_CONVERGE;
} }
void System::Clear() { void System::Clear() {

View File

@ -11,7 +11,7 @@
// link to bring us back home. // link to bring us back home.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void TextWindow::ScreenHome(int link, uint32_t v) { void TextWindow::ScreenHome(int link, uint32_t v) {
SS.TW.GoToScreen(SCREEN_LIST_OF_GROUPS); SS.TW.GoToScreen(Screen::LIST_OF_GROUPS);
} }
void TextWindow::ShowHeader(bool withNav) { void TextWindow::ShowHeader(bool withNav) {
ClearScreen(); ClearScreen();
@ -44,7 +44,7 @@ void TextWindow::ShowHeader(bool withNav) {
// to hide or show them, and to view them in detail. This is our home page. // to hide or show them, and to view them in detail. This is our home page.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void TextWindow::ScreenSelectGroup(int link, uint32_t v) { void TextWindow::ScreenSelectGroup(int link, uint32_t v) {
SS.TW.GoToScreen(SCREEN_GROUP_INFO); SS.TW.GoToScreen(Screen::GROUP_INFO);
SS.TW.shown.group.v = v; SS.TW.shown.group.v = v;
} }
void TextWindow::ScreenToggleGroupShown(int link, uint32_t v) { void TextWindow::ScreenToggleGroupShown(int link, uint32_t v) {
@ -69,7 +69,7 @@ void TextWindow::ScreenActivateGroup(int link, uint32_t v) {
} }
void TextWindow::ReportHowGroupSolved(hGroup hg) { void TextWindow::ReportHowGroupSolved(hGroup hg) {
SS.GW.ClearSuper(); SS.GW.ClearSuper();
SS.TW.GoToScreen(SCREEN_GROUP_SOLVE_INFO); SS.TW.GoToScreen(Screen::GROUP_SOLVE_INFO);
SS.TW.shown.group.v = hg.v; SS.TW.shown.group.v = hg.v;
SS.ScheduleShowTW(); SS.ScheduleShowTW();
} }
@ -77,14 +77,14 @@ void TextWindow::ScreenHowGroupSolved(int link, uint32_t v) {
if(SS.GW.activeGroup.v != v) { if(SS.GW.activeGroup.v != v) {
ScreenActivateGroup(link, v); ScreenActivateGroup(link, v);
} }
SS.TW.GoToScreen(SCREEN_GROUP_SOLVE_INFO); SS.TW.GoToScreen(Screen::GROUP_SOLVE_INFO);
SS.TW.shown.group.v = v; SS.TW.shown.group.v = v;
} }
void TextWindow::ScreenShowConfiguration(int link, uint32_t v) { void TextWindow::ScreenShowConfiguration(int link, uint32_t v) {
SS.TW.GoToScreen(SCREEN_CONFIGURATION); SS.TW.GoToScreen(Screen::CONFIGURATION);
} }
void TextWindow::ScreenShowEditView(int link, uint32_t v) { void TextWindow::ScreenShowEditView(int link, uint32_t v) {
SS.TW.GoToScreen(SCREEN_EDIT_VIEW); SS.TW.GoToScreen(Screen::EDIT_VIEW);
} }
void TextWindow::ScreenGoToWebsite(int link, uint32_t v) { void TextWindow::ScreenGoToWebsite(int link, uint32_t v) {
OpenWebsite("http://solvespace.com/txtlink"); OpenWebsite("http://solvespace.com/txtlink");
@ -185,8 +185,8 @@ void TextWindow::ScreenChangeGroupOption(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
switch(link) { switch(link) {
case 's': g->subtype = Group::ONE_SIDED; break; case 's': g->subtype = Group::Subtype::ONE_SIDED; break;
case 'S': g->subtype = Group::TWO_SIDED; break; case 'S': g->subtype = Group::Subtype::TWO_SIDED; break;
case 'k': g->skipFirst = true; break; case 'k': g->skipFirst = true; break;
case 'K': g->skipFirst = false; break; case 'K': g->skipFirst = false; break;
@ -195,12 +195,12 @@ void TextWindow::ScreenChangeGroupOption(int link, uint32_t v) {
// When an extrude group is first created, it's positioned for a union // When an extrude group is first created, it's positioned for a union
// extrusion. If no constraints were added, flip it when we switch between // extrusion. If no constraints were added, flip it when we switch between
// union and difference modes to avoid manual work doing the smae. // union and difference modes to avoid manual work doing the smae.
if(g->meshCombine != (int)v && g->GetNumConstraints() == 0 && if(g->meshCombine != (Group::CombineAs)v && g->GetNumConstraints() == 0 &&
(v == Group::COMBINE_AS_DIFFERENCE || ((Group::CombineAs)v == Group::CombineAs::DIFFERENCE ||
g->meshCombine == Group::COMBINE_AS_DIFFERENCE)) { g->meshCombine == Group::CombineAs::DIFFERENCE)) {
g->ExtrusionForceVectorTo(g->ExtrusionGetVector().Negated()); g->ExtrusionForceVectorTo(g->ExtrusionGetVector().Negated());
} }
g->meshCombine = v; g->meshCombine = (Group::CombineAs)v;
break; break;
case 'P': g->suppress = !(g->suppress); break; case 'P': g->suppress = !(g->suppress); break;
@ -226,33 +226,33 @@ void TextWindow::ScreenColor(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
SS.TW.ShowEditControlWithColorPicker(3, g->color); SS.TW.ShowEditControlWithColorPicker(3, g->color);
SS.TW.edit.meaning = EDIT_GROUP_COLOR; SS.TW.edit.meaning = Edit::GROUP_COLOR;
} }
void TextWindow::ScreenOpacity(int link, uint32_t v) { void TextWindow::ScreenOpacity(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
SS.TW.ShowEditControl(11, ssprintf("%.2f", g->color.alphaF())); SS.TW.ShowEditControl(11, ssprintf("%.2f", g->color.alphaF()));
SS.TW.edit.meaning = EDIT_GROUP_OPACITY; SS.TW.edit.meaning = Edit::GROUP_OPACITY;
SS.TW.edit.group.v = g->h.v; SS.TW.edit.group.v = g->h.v;
} }
void TextWindow::ScreenChangeExprA(int link, uint32_t v) { void TextWindow::ScreenChangeExprA(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
SS.TW.ShowEditControl(10, ssprintf("%d", (int)g->valA)); SS.TW.ShowEditControl(10, ssprintf("%d", (int)g->valA));
SS.TW.edit.meaning = EDIT_TIMES_REPEATED; SS.TW.edit.meaning = Edit::TIMES_REPEATED;
SS.TW.edit.group.v = v; SS.TW.edit.group.v = v;
} }
void TextWindow::ScreenChangeGroupName(int link, uint32_t v) { void TextWindow::ScreenChangeGroupName(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
SS.TW.ShowEditControl(12, g->DescriptionString().substr(5)); SS.TW.ShowEditControl(12, g->DescriptionString().substr(5));
SS.TW.edit.meaning = EDIT_GROUP_NAME; SS.TW.edit.meaning = Edit::GROUP_NAME;
SS.TW.edit.group.v = v; SS.TW.edit.group.v = v;
} }
void TextWindow::ScreenChangeGroupScale(int link, uint32_t v) { void TextWindow::ScreenChangeGroupScale(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group); Group *g = SK.GetGroup(SS.TW.shown.group);
SS.TW.ShowEditControl(13, ssprintf("%.3f", g->scale)); SS.TW.ShowEditControl(13, ssprintf("%.3f", g->scale));
SS.TW.edit.meaning = EDIT_GROUP_SCALE; SS.TW.edit.meaning = Edit::GROUP_SCALE;
SS.TW.edit.group.v = v; SS.TW.edit.group.v = v;
} }
void TextWindow::ScreenDeleteGroup(int link, uint32_t v) { void TextWindow::ScreenDeleteGroup(int link, uint32_t v) {
@ -269,7 +269,7 @@ void TextWindow::ScreenDeleteGroup(int link, uint32_t v) {
// This is a major change, so let's re-solve everything. // This is a major change, so let's re-solve everything.
SK.group.RemoveById(hg); SK.group.RemoveById(hg);
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
// Reset the graphics window. This will also recreate the default // Reset the graphics window. This will also recreate the default
// group if it was removed. // group if it was removed.
@ -289,21 +289,21 @@ void TextWindow::ShowGroupInfo() {
g->h.v, &TextWindow::ScreenDeleteGroup); g->h.v, &TextWindow::ScreenDeleteGroup);
} }
if(g->type == Group::LATHE) { if(g->type == Group::Type::LATHE) {
Printf(true, " %Ftlathe plane sketch"); Printf(true, " %Ftlathe plane sketch");
} else if(g->type == Group::EXTRUDE || g->type == Group::ROTATE || } else if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::ROTATE ||
g->type == Group::TRANSLATE) g->type == Group::Type::TRANSLATE)
{ {
if(g->type == Group::EXTRUDE) { if(g->type == Group::Type::EXTRUDE) {
s = "extrude plane sketch"; s = "extrude plane sketch";
} else if(g->type == Group::TRANSLATE) { } else if(g->type == Group::Type::TRANSLATE) {
s = "translate original sketch"; s = "translate original sketch";
} else if(g->type == Group::ROTATE) { } else if(g->type == Group::Type::ROTATE) {
s = "rotate original sketch"; s = "rotate original sketch";
} }
Printf(true, " %Ft%s%E", s); Printf(true, " %Ft%s%E", s);
bool one = (g->subtype == Group::ONE_SIDED); bool one = (g->subtype == Group::Subtype::ONE_SIDED);
Printf(false, Printf(false,
"%Ba %f%Ls%Fd%s one-sided%E " "%Ba %f%Ls%Fd%s one-sided%E "
"%f%LS%Fd%s two-sided%E", "%f%LS%Fd%s two-sided%E",
@ -312,8 +312,8 @@ void TextWindow::ShowGroupInfo() {
&TextWindow::ScreenChangeGroupOption, &TextWindow::ScreenChangeGroupOption,
!one ? RADIO_TRUE : RADIO_FALSE); !one ? RADIO_TRUE : RADIO_FALSE);
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) { if(g->type == Group::Type::ROTATE || g->type == Group::Type::TRANSLATE) {
if(g->subtype == Group::ONE_SIDED) { if(g->subtype == Group::Subtype::ONE_SIDED) {
bool skip = g->skipFirst; bool skip = g->skipFirst;
Printf(false, Printf(false,
"%Bd %Ftstart %f%LK%Fd%s with original%E " "%Bd %Ftstart %f%LK%Fd%s with original%E "
@ -326,51 +326,51 @@ void TextWindow::ShowGroupInfo() {
int times = (int)(g->valA); int times = (int)(g->valA);
Printf(false, "%Bp %Ftrepeat%E %d time%s %Fl%Ll%D%f[change]%E", Printf(false, "%Bp %Ftrepeat%E %d time%s %Fl%Ll%D%f[change]%E",
(g->subtype == Group::ONE_SIDED) ? 'a' : 'd', (g->subtype == Group::Subtype::ONE_SIDED) ? 'a' : 'd',
times, times == 1 ? "" : "s", times, times == 1 ? "" : "s",
g->h.v, &TextWindow::ScreenChangeExprA); g->h.v, &TextWindow::ScreenChangeExprA);
} }
} else if(g->type == Group::LINKED) { } else if(g->type == Group::Type::LINKED) {
Printf(true, " %Ftlink geometry from file%E"); Printf(true, " %Ftlink geometry from file%E");
Printf(false, "%Ba '%s'", g->linkFileRel.c_str()); Printf(false, "%Ba '%s'", g->linkFileRel.c_str());
Printf(false, "%Bd %Ftscaled by%E %# %Fl%Ll%f%D[change]%E", Printf(false, "%Bd %Ftscaled by%E %# %Fl%Ll%f%D[change]%E",
g->scale, g->scale,
&TextWindow::ScreenChangeGroupScale, g->h.v); &TextWindow::ScreenChangeGroupScale, g->h.v);
} else if(g->type == Group::DRAWING_3D) { } else if(g->type == Group::Type::DRAWING_3D) {
Printf(true, " %Ftsketch in 3d%E"); Printf(true, " %Ftsketch in 3d%E");
} else if(g->type == Group::DRAWING_WORKPLANE) { } else if(g->type == Group::Type::DRAWING_WORKPLANE) {
Printf(true, " %Ftsketch in new workplane%E"); Printf(true, " %Ftsketch in new workplane%E");
} else { } else {
Printf(true, "???"); Printf(true, "???");
} }
Printf(false, ""); Printf(false, "");
if(g->type == Group::EXTRUDE || if(g->type == Group::Type::EXTRUDE ||
g->type == Group::LATHE || g->type == Group::Type::LATHE ||
g->type == Group::LINKED) g->type == Group::Type::LINKED)
{ {
bool un = (g->meshCombine == Group::COMBINE_AS_UNION); bool un = (g->meshCombine == Group::CombineAs::UNION);
bool diff = (g->meshCombine == Group::COMBINE_AS_DIFFERENCE); bool diff = (g->meshCombine == Group::CombineAs::DIFFERENCE);
bool asy = (g->meshCombine == Group::COMBINE_AS_ASSEMBLE); bool asy = (g->meshCombine == Group::CombineAs::ASSEMBLE);
bool asa = (g->type == Group::LINKED); bool asa = (g->type == Group::Type::LINKED);
Printf(false, " %Ftsolid model as"); Printf(false, " %Ftsolid model as");
Printf(false, "%Ba %f%D%Lc%Fd%s union%E " Printf(false, "%Ba %f%D%Lc%Fd%s union%E "
"%f%D%Lc%Fd%s difference%E " "%f%D%Lc%Fd%s difference%E "
"%f%D%Lc%Fd%s%s%E ", "%f%D%Lc%Fd%s%s%E ",
&TextWindow::ScreenChangeGroupOption, &TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_UNION, Group::CombineAs::UNION,
un ? RADIO_TRUE : RADIO_FALSE, un ? RADIO_TRUE : RADIO_FALSE,
&TextWindow::ScreenChangeGroupOption, &TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_DIFFERENCE, Group::CombineAs::DIFFERENCE,
diff ? RADIO_TRUE : RADIO_FALSE, diff ? RADIO_TRUE : RADIO_FALSE,
&TextWindow::ScreenChangeGroupOption, &TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_ASSEMBLE, Group::CombineAs::ASSEMBLE,
asa ? (asy ? RADIO_TRUE : RADIO_FALSE) : " ", asa ? (asy ? RADIO_TRUE : RADIO_FALSE) : " ",
asa ? " assemble" : ""); asa ? " assemble" : "");
if(g->type == Group::EXTRUDE || if(g->type == Group::Type::EXTRUDE ||
g->type == Group::LATHE) g->type == Group::Type::LATHE)
{ {
Printf(false, Printf(false,
"%Bd %Ftcolor %E%Bz %Bd (%@, %@, %@) %f%D%Lf%Fl[change]%E", "%Bd %Ftcolor %E%Bz %Bd (%@, %@, %@) %f%D%Lf%Fl[change]%E",
@ -380,7 +380,7 @@ void TextWindow::ShowGroupInfo() {
Printf(false, "%Bd %Ftopacity%E %@ %f%Lf%Fl[change]%E", Printf(false, "%Bd %Ftopacity%E %@ %f%Lf%Fl[change]%E",
g->color.alphaF(), g->color.alphaF(),
&TextWindow::ScreenOpacity); &TextWindow::ScreenOpacity);
} else if(g->type == Group::LINKED) { } else if(g->type == Group::Type::LINKED) {
Printf(false, " %Fd%f%LP%s suppress this group's solid model", Printf(false, " %Fd%f%LP%s suppress this group's solid model",
&TextWindow::ScreenChangeGroupOption, &TextWindow::ScreenChangeGroupOption,
g->suppress ? CHECK_TRUE : CHECK_FALSE); g->suppress ? CHECK_TRUE : CHECK_FALSE);
@ -471,36 +471,36 @@ void TextWindow::ScreenAllowRedundant(int link, uint32_t v) {
g->allowRedundant = true; g->allowRedundant = true;
SS.GenerateAll(); SS.GenerateAll();
SS.TW.shown.screen = SCREEN_GROUP_INFO; SS.TW.shown.screen = Screen::GROUP_INFO;
SS.TW.Show(); SS.TW.Show();
} }
void TextWindow::ShowGroupSolveInfo() { void TextWindow::ShowGroupSolveInfo() {
Group *g = SK.GetGroup(shown.group); Group *g = SK.GetGroup(shown.group);
if(g->IsSolvedOkay()) { if(g->IsSolvedOkay()) {
// Go back to the default group info screen // Go back to the default group info screen
shown.screen = SCREEN_GROUP_INFO; shown.screen = Screen::GROUP_INFO;
Show(); Show();
return; return;
} }
Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str()); Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str());
switch(g->solved.how) { switch(g->solved.how) {
case System::DIDNT_CONVERGE: case SolveResult::DIDNT_CONVERGE:
Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints"); Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints");
Printf(true, "the following constraints are incompatible"); Printf(true, "the following constraints are incompatible");
break; break;
case System::REDUNDANT_DIDNT_CONVERGE: case SolveResult::REDUNDANT_DIDNT_CONVERGE:
Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints"); Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints");
Printf(true, "the following constraints are unsatisfied"); Printf(true, "the following constraints are unsatisfied");
break; break;
case System::REDUNDANT_OKAY: case SolveResult::REDUNDANT_OKAY:
Printf(true, "%FxSOLVE FAILED!%Fd redundant constraints"); Printf(true, "%FxSOLVE FAILED!%Fd redundant constraints");
Printf(true, "remove any one of these to fix it"); Printf(true, "remove any one of these to fix it");
break; break;
case System::TOO_MANY_UNKNOWNS: case SolveResult::TOO_MANY_UNKNOWNS:
Printf(true, "Too many unknowns in a single group!"); Printf(true, "Too many unknowns in a single group!");
return; return;
} }
@ -520,7 +520,7 @@ void TextWindow::ShowGroupSolveInfo() {
Printf(true, "It may be possible to fix the problem "); Printf(true, "It may be possible to fix the problem ");
Printf(false, "by selecting Edit -> Undo."); Printf(false, "by selecting Edit -> Undo.");
if(g->solved.how == System::REDUNDANT_OKAY) { if(g->solved.how == SolveResult::REDUNDANT_OKAY) {
Printf(true, "It is possible to suppress this error "); Printf(true, "It is possible to suppress this error ");
Printf(false, "by %Fl%f%Llallowing redundant constraints%E in ", Printf(false, "by %Fl%f%Llallowing redundant constraints%E in ",
&TextWindow::ScreenAllowRedundant); &TextWindow::ScreenAllowRedundant);
@ -534,7 +534,7 @@ void TextWindow::ShowGroupSolveInfo() {
// time. // time.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void TextWindow::ScreenStepDimFinish(int link, uint32_t v) { void TextWindow::ScreenStepDimFinish(int link, uint32_t v) {
SS.TW.edit.meaning = EDIT_STEP_DIM_FINISH; SS.TW.edit.meaning = Edit::STEP_DIM_FINISH;
std::string edit_value; std::string edit_value;
if(SS.TW.shown.dimIsDistance) { if(SS.TW.shown.dimIsDistance) {
edit_value = SS.MmToString(SS.TW.shown.dimFinish); edit_value = SS.MmToString(SS.TW.shown.dimFinish);
@ -544,7 +544,7 @@ void TextWindow::ScreenStepDimFinish(int link, uint32_t v) {
SS.TW.ShowEditControl(12, edit_value); SS.TW.ShowEditControl(12, edit_value);
} }
void TextWindow::ScreenStepDimSteps(int link, uint32_t v) { void TextWindow::ScreenStepDimSteps(int link, uint32_t v) {
SS.TW.edit.meaning = EDIT_STEP_DIM_STEPS; SS.TW.edit.meaning = Edit::STEP_DIM_STEPS;
SS.TW.ShowEditControl(12, ssprintf("%d", SS.TW.shown.dimSteps)); SS.TW.ShowEditControl(12, ssprintf("%d", SS.TW.shown.dimSteps));
} }
void TextWindow::ScreenStepDimGo(int link, uint32_t v) { void TextWindow::ScreenStepDimGo(int link, uint32_t v) {
@ -567,12 +567,12 @@ void TextWindow::ScreenStepDimGo(int link, uint32_t v) {
} }
} }
InvalidateGraphics(); InvalidateGraphics();
SS.TW.GoToScreen(SCREEN_LIST_OF_GROUPS); SS.TW.GoToScreen(Screen::LIST_OF_GROUPS);
} }
void TextWindow::ShowStepDimension() { void TextWindow::ShowStepDimension() {
Constraint *c = SK.constraint.FindByIdNoOops(shown.constraint); Constraint *c = SK.constraint.FindByIdNoOops(shown.constraint);
if(!c) { if(!c) {
shown.screen = SCREEN_LIST_OF_GROUPS; shown.screen = Screen::LIST_OF_GROUPS;
Show(); Show();
return; return;
} }
@ -604,7 +604,7 @@ void TextWindow::ShowStepDimension() {
void TextWindow::ScreenChangeTangentArc(int link, uint32_t v) { void TextWindow::ScreenChangeTangentArc(int link, uint32_t v) {
switch(link) { switch(link) {
case 'r': { case 'r': {
SS.TW.edit.meaning = EDIT_TANGENT_ARC_RADIUS; SS.TW.edit.meaning = Edit::TANGENT_ARC_RADIUS;
SS.TW.ShowEditControl(3, SS.MmToString(SS.tangentArcRadius)); SS.TW.ShowEditControl(3, SS.MmToString(SS.tangentArcRadius));
break; break;
} }
@ -647,7 +647,7 @@ void TextWindow::EditControlDone(const char *s) {
edit.showAgain = false; edit.showAgain = false;
switch(edit.meaning) { switch(edit.meaning) {
case EDIT_TIMES_REPEATED: { case Edit::TIMES_REPEATED: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) { if(e) {
SS.UndoRemember(); SS.UndoRemember();
@ -665,7 +665,7 @@ void TextWindow::EditControlDone(const char *s) {
Group *g = SK.GetGroup(edit.group); Group *g = SK.GetGroup(edit.group);
g->valA = ev; g->valA = ev;
if(g->type == Group::ROTATE) { if(g->type == Group::Type::ROTATE) {
int i, c = 0; int i, c = 0;
for(i = 0; i < SK.constraint.n; i++) { for(i = 0; i < SK.constraint.n; i++) {
if(SK.constraint.elem[i].group.v == g->h.v) c++; if(SK.constraint.elem[i].group.v == g->h.v) c++;
@ -686,7 +686,7 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_GROUP_NAME: { case Edit::GROUP_NAME: {
if(!*s) { if(!*s) {
Error("Group name cannot be empty"); Error("Group name cannot be empty");
} else { } else {
@ -697,7 +697,7 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_GROUP_SCALE: { case Edit::GROUP_SCALE: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double ev = e->Eval(); double ev = e->Eval();
@ -712,7 +712,7 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_GROUP_COLOR: { case Edit::GROUP_COLOR: {
Vector rgb; Vector rgb;
if(sscanf(s, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { if(sscanf(s, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) {
rgb = rgb.ClampWithin(0, 1); rgb = rgb.ClampWithin(0, 1);
@ -729,7 +729,7 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_GROUP_OPACITY: { case Edit::GROUP_OPACITY: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double alpha = e->Eval(); double alpha = e->Eval();
@ -745,7 +745,7 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_TTF_TEXT: { case Edit::TTF_TEXT: {
SS.UndoRemember(); SS.UndoRemember();
Request *r = SK.request.FindByIdNoOops(edit.request); Request *r = SK.request.FindByIdNoOops(edit.request);
if(r) { if(r) {
@ -755,7 +755,7 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_STEP_DIM_FINISH: { case Edit::STEP_DIM_FINISH: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(!e) { if(!e) {
break; break;
@ -767,11 +767,11 @@ void TextWindow::EditControlDone(const char *s) {
} }
break; break;
} }
case EDIT_STEP_DIM_STEPS: case Edit::STEP_DIM_STEPS:
shown.dimSteps = min(300, max(1, atoi(s))); shown.dimSteps = min(300, max(1, atoi(s)));
break; break;
case EDIT_TANGENT_ARC_RADIUS: { case Edit::TANGENT_ARC_RADIUS: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(!e) break; if(!e) break;
if(e->Eval() < LENGTH_EPS) { if(e->Eval() < LENGTH_EPS) {
@ -797,7 +797,7 @@ void TextWindow::EditControlDone(const char *s) {
if(!edit.showAgain) { if(!edit.showAgain) {
HideEditControl(); HideEditControl();
edit.meaning = EDIT_NOTHING; edit.meaning = Edit::NOTHING;
} }
} }

View File

@ -299,28 +299,28 @@ void TextWindow::Show() {
Printf(true, "%Fl%f%Ll(cancel operation)%E", Printf(true, "%Fl%f%Ll(cancel operation)%E",
&TextWindow::ScreenUnselectAll); &TextWindow::ScreenUnselectAll);
} else if((gs.n > 0 || gs.constraints > 0) && } else if((gs.n > 0 || gs.constraints > 0) &&
shown.screen != SCREEN_PASTE_TRANSFORMED) shown.screen != Screen::PASTE_TRANSFORMED)
{ {
if(edit.meaning != EDIT_TTF_TEXT) HideEditControl(); if(edit.meaning != Edit::TTF_TEXT) HideEditControl();
ShowHeader(false); ShowHeader(false);
DescribeSelection(); DescribeSelection();
} else { } else {
if(edit.meaning == EDIT_TTF_TEXT) HideEditControl(); if(edit.meaning == Edit::TTF_TEXT) HideEditControl();
ShowHeader(true); ShowHeader(true);
switch(shown.screen) { switch(shown.screen) {
default: default:
shown.screen = SCREEN_LIST_OF_GROUPS; shown.screen = Screen::LIST_OF_GROUPS;
// fall through // fall through
case SCREEN_LIST_OF_GROUPS: ShowListOfGroups(); break; case Screen::LIST_OF_GROUPS: ShowListOfGroups(); break;
case SCREEN_GROUP_INFO: ShowGroupInfo(); break; case Screen::GROUP_INFO: ShowGroupInfo(); break;
case SCREEN_GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break; case Screen::GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break;
case SCREEN_CONFIGURATION: ShowConfiguration(); break; case Screen::CONFIGURATION: ShowConfiguration(); break;
case SCREEN_STEP_DIMENSION: ShowStepDimension(); break; case Screen::STEP_DIMENSION: ShowStepDimension(); break;
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; case Screen::EDIT_VIEW: ShowEditView(); break;
case SCREEN_TANGENT_ARC: ShowTangentArc(); break; case Screen::TANGENT_ARC: ShowTangentArc(); break;
} }
} }
Printf(false, ""); Printf(false, "");
@ -344,7 +344,7 @@ void TextWindow::TimerCallback()
InvalidateText(); InvalidateText();
} }
void TextWindow::DrawOrHitTestIcons(int how, double mx, double my) void TextWindow::DrawOrHitTestIcons(TextWindow::DrawOrHitHow how, double mx, double my)
{ {
int width, height; int width, height;
GetTextWindowSize(&width, &height); GetTextWindowSize(&width, &height);
@ -549,7 +549,7 @@ void TextWindow::ColorPickerDone() {
EditControlDone(ssprintf("%.2f, %.2f, %.3f", rgb.redF(), rgb.greenF(), rgb.blueF()).c_str()); EditControlDone(ssprintf("%.2f, %.2f, %.3f", rgb.redF(), rgb.greenF(), rgb.blueF()).c_str());
} }
bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown, bool TextWindow::DrawOrHitTestColorPicker(DrawOrHitHow how, bool leftDown,
double x, double y) double x, double y)
{ {
bool mousePointerAsHand = false; bool mousePointerAsHand = false;
@ -933,7 +933,7 @@ void TextWindow::Paint() {
SS.GW.GroupSelection(); SS.GW.GroupSelection();
// Make sure this test agrees with test to determine which screen is drawn // Make sure this test agrees with test to determine which screen is drawn
if(!SS.GW.pending.description && gs.n == 0 && gs.constraints == 0 && if(!SS.GW.pending.description && gs.n == 0 && gs.constraints == 0 &&
shown.screen == SCREEN_LIST_OF_GROUPS) shown.screen == Screen::LIST_OF_GROUPS)
{ {
int x = 29, y = 70 + LINE_HEIGHT; int x = 29, y = 70 + LINE_HEIGHT;
y -= scrollPos*(LINE_HEIGHT/2); y -= scrollPos*(LINE_HEIGHT/2);

View File

@ -10,48 +10,48 @@
static const char *SPACER = ""; static const char *SPACER = "";
static struct { static struct {
const char *iconName; const char *iconName;
int menu; Command menu;
const char *tip; const char *tip;
Pixmap icon; Pixmap icon;
} Toolbar[] = { } Toolbar[] = {
{ "line", GraphicsWindow::MNU_LINE_SEGMENT, "Sketch line segment", {} }, { "line", Command::LINE_SEGMENT, "Sketch line segment", {} },
{ "rectangle", GraphicsWindow::MNU_RECTANGLE, "Sketch rectangle", {} }, { "rectangle", Command::RECTANGLE, "Sketch rectangle", {} },
{ "circle", GraphicsWindow::MNU_CIRCLE, "Sketch circle", {} }, { "circle", Command::CIRCLE, "Sketch circle", {} },
{ "arc", GraphicsWindow::MNU_ARC, "Sketch arc of a circle", {} }, { "arc", Command::ARC, "Sketch arc of a circle", {} },
{ "text", GraphicsWindow::MNU_TTF_TEXT, "Sketch curves from text in a TrueType font", {} }, { "text", Command::TTF_TEXT, "Sketch curves from text in a TrueType font", {} },
{ "tangent-arc", GraphicsWindow::MNU_TANGENT_ARC, "Create tangent arc at selected point", {} }, { "tangent-arc", Command::TANGENT_ARC, "Create tangent arc at selected point", {} },
{ "bezier", GraphicsWindow::MNU_CUBIC, "Sketch cubic Bezier spline", {} }, { "bezier", Command::CUBIC, "Sketch cubic Bezier spline", {} },
{ "point", GraphicsWindow::MNU_DATUM_POINT, "Sketch datum point", {} }, { "point", Command::DATUM_POINT, "Sketch datum point", {} },
{ "construction", GraphicsWindow::MNU_CONSTRUCTION, "Toggle construction", {} }, { "construction", Command::CONSTRUCTION, "Toggle construction", {} },
{ "trim", GraphicsWindow::MNU_SPLIT_CURVES, "Split lines / curves where they intersect", {} }, { "trim", Command::SPLIT_CURVES, "Split lines / curves where they intersect", {} },
{ SPACER, 0, 0, {} }, { SPACER, Command::NONE, 0, {} },
{ "length", GraphicsWindow::MNU_DISTANCE_DIA, "Constrain distance / diameter / length", {} }, { "length", Command::DISTANCE_DIA, "Constrain distance / diameter / length", {} },
{ "angle", GraphicsWindow::MNU_ANGLE, "Constrain angle", {} }, { "angle", Command::ANGLE, "Constrain angle", {} },
{ "horiz", GraphicsWindow::MNU_HORIZONTAL, "Constrain to be horizontal", {} }, { "horiz", Command::HORIZONTAL, "Constrain to be horizontal", {} },
{ "vert", GraphicsWindow::MNU_VERTICAL, "Constrain to be vertical", {} }, { "vert", Command::VERTICAL, "Constrain to be vertical", {} },
{ "parallel", GraphicsWindow::MNU_PARALLEL, "Constrain to be parallel or tangent", {} }, { "parallel", Command::PARALLEL, "Constrain to be parallel or tangent", {} },
{ "perpendicular", GraphicsWindow::MNU_PERPENDICULAR, "Constrain to be perpendicular", {} }, { "perpendicular", Command::PERPENDICULAR, "Constrain to be perpendicular", {} },
{ "pointonx", GraphicsWindow::MNU_ON_ENTITY, "Constrain point on line / curve / plane / point", {} }, { "pointonx", Command::ON_ENTITY, "Constrain point on line / curve / plane / point", {} },
{ "symmetric", GraphicsWindow::MNU_SYMMETRIC, "Constrain symmetric", {} }, { "symmetric", Command::SYMMETRIC, "Constrain symmetric", {} },
{ "equal", GraphicsWindow::MNU_EQUAL, "Constrain equal length / radius / angle", {} }, { "equal", Command::EQUAL, "Constrain equal length / radius / angle", {} },
{ "same-orientation",GraphicsWindow::MNU_ORIENTED_SAME, "Constrain normals in same orientation", {} }, { "same-orientation",Command::ORIENTED_SAME, "Constrain normals in same orientation", {} },
{ "other-supp", GraphicsWindow::MNU_OTHER_ANGLE, "Other supplementary angle", {} }, { "other-supp", Command::OTHER_ANGLE, "Other supplementary angle", {} },
{ "ref", GraphicsWindow::MNU_REFERENCE, "Toggle reference dimension", {} }, { "ref", Command::REFERENCE, "Toggle reference dimension", {} },
{ SPACER, 0, 0, {} }, { SPACER, Command::NONE, 0, {} },
{ "extrude", GraphicsWindow::MNU_GROUP_EXTRUDE, "New group extruding active sketch", {} }, { "extrude", Command::GROUP_EXTRUDE, "New group extruding active sketch", {} },
{ "lathe", GraphicsWindow::MNU_GROUP_LATHE, "New group rotating active sketch", {} }, { "lathe", Command::GROUP_LATHE, "New group rotating active sketch", {} },
{ "step-rotate", GraphicsWindow::MNU_GROUP_ROT, "New group step and repeat rotating", {} }, { "step-rotate", Command::GROUP_ROT, "New group step and repeat rotating", {} },
{ "step-translate", GraphicsWindow::MNU_GROUP_TRANS, "New group step and repeat translating", {} }, { "step-translate", Command::GROUP_TRANS, "New group step and repeat translating", {} },
{ "sketch-in-plane", GraphicsWindow::MNU_GROUP_WRKPL, "New group in new workplane (thru given entities)", {} }, { "sketch-in-plane", Command::GROUP_WRKPL, "New group in new workplane (thru given entities)", {} },
{ "sketch-in-3d", GraphicsWindow::MNU_GROUP_3D, "New group in 3d", {} }, { "sketch-in-3d", Command::GROUP_3D, "New group in 3d", {} },
{ "assemble", GraphicsWindow::MNU_GROUP_LINK, "New group linking / assembling file", {} }, { "assemble", Command::GROUP_LINK, "New group linking / assembling file", {} },
{ SPACER, 0, 0, {} }, { SPACER, Command::NONE, 0, {} },
{ "in3d", GraphicsWindow::MNU_NEAREST_ISO, "Nearest isometric view", {} }, { "in3d", Command::NEAREST_ISO, "Nearest isometric view", {} },
{ "ontoworkplane", GraphicsWindow::MNU_ONTO_WORKPLANE, "Align view to active workplane", {} }, { "ontoworkplane", Command::ONTO_WORKPLANE, "Align view to active workplane", {} },
{ NULL, 0, 0, {} } { NULL, Command::NONE, 0, {} }
}; };
void GraphicsWindow::ToolbarDraw() { void GraphicsWindow::ToolbarDraw() {
@ -62,16 +62,16 @@ bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
x += ((int)width/2); x += ((int)width/2);
y += ((int)height/2); y += ((int)height/2);
int nh = 0; Command nh = Command::NONE;
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
if(!withinToolbar) nh = 0; if(!withinToolbar) nh = Command::NONE;
if(nh != toolbarTooltipped) { if(nh != toolbarTooltipped) {
// Don't let the tool tip move around if the mouse moves within the // Don't let the tool tip move around if the mouse moves within the
// same item. // same item.
toolbarMouseX = x; toolbarMouseX = x;
toolbarMouseY = y; toolbarMouseY = y;
toolbarTooltipped = 0; toolbarTooltipped = Command::NONE;
} }
if(nh != toolbarHovered) { if(nh != toolbarHovered) {
@ -89,13 +89,13 @@ bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
x += ((int)width/2); x += ((int)width/2);
y += ((int)height/2); y += ((int)height/2);
int nh = -1; Command nh = Command::NONE;
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
// They might have clicked within the toolbar, but not on a button. // They might have clicked within the toolbar, but not on a button.
if(withinToolbar && nh >= 0) { if(withinToolbar && nh != Command::NONE) {
for(int i = 0; SS.GW.menu[i].level >= 0; i++) { for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
if(nh == SS.GW.menu[i].id) { if(nh == SS.GW.menu[i].id) {
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)SS.GW.menu[i].id); (SS.GW.menu[i].fn)((Command)SS.GW.menu[i].id);
break; break;
} }
} }
@ -104,7 +104,7 @@ bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
} }
bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
bool paint, int *menuHit) bool paint, Command *menuHit)
{ {
int i; int i;
int x = 17, y = (int)(height - 52); int x = 17, y = (int)(height - 52);
@ -176,7 +176,7 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my,
ssglDrawPixmap(Toolbar[i].icon, o, /*flip=*/true); ssglDrawPixmap(Toolbar[i].icon, o, /*flip=*/true);
if(toolbarHovered == Toolbar[i].menu || if(toolbarHovered == Toolbar[i].menu ||
pending.operation == Toolbar[i].menu) { pending.operation == (uint32_t)Toolbar[i].menu) {
// Highlight the hovered or pending item. // Highlight the hovered or pending item.
glColor4d(1, 1, 0, 0.3); glColor4d(1, 1, 0, 0.3);
int boxhw = 15; int boxhw = 15;

424
src/ui.h
View File

@ -8,6 +8,144 @@
#ifndef __UI_H #ifndef __UI_H
#define __UI_H #define __UI_H
#ifdef WIN32
// winnt.h
#undef DELETE
#endif
// This table describes the top-level menus in the graphics winodw.
enum class Command : uint32_t {
NONE = 0,
// File
NEW = 100,
OPEN,
OPEN_RECENT,
SAVE,
SAVE_AS,
EXPORT_PNG,
EXPORT_MESH,
EXPORT_SURFACES,
EXPORT_VIEW,
EXPORT_SECTION,
EXPORT_WIREFRAME,
IMPORT,
EXIT,
// View
ZOOM_IN,
ZOOM_OUT,
ZOOM_TO_FIT,
SHOW_GRID,
PERSPECTIVE_PROJ,
ONTO_WORKPLANE,
NEAREST_ORTHO,
NEAREST_ISO,
CENTER_VIEW,
SHOW_MENU_BAR,
SHOW_TOOLBAR,
SHOW_TEXT_WND,
UNITS_INCHES,
UNITS_MM,
FULL_SCREEN,
// Edit
UNDO,
REDO,
CUT,
COPY,
PASTE,
PASTE_TRANSFORM,
DELETE,
SELECT_CHAIN,
SELECT_ALL,
SNAP_TO_GRID,
ROTATE_90,
UNSELECT_ALL,
REGEN_ALL,
// Request
SEL_WORKPLANE,
FREE_IN_3D,
DATUM_POINT,
WORKPLANE,
LINE_SEGMENT,
CONSTR_SEGMENT,
CIRCLE,
ARC,
RECTANGLE,
CUBIC,
TTF_TEXT,
SPLIT_CURVES,
TANGENT_ARC,
CONSTRUCTION,
// Group
GROUP_3D,
GROUP_WRKPL,
GROUP_EXTRUDE,
GROUP_LATHE,
GROUP_ROT,
GROUP_TRANS,
GROUP_LINK,
GROUP_RECENT,
// Constrain
DISTANCE_DIA,
REF_DISTANCE,
ANGLE,
REF_ANGLE,
OTHER_ANGLE,
REFERENCE,
EQUAL,
RATIO,
DIFFERENCE,
ON_ENTITY,
SYMMETRIC,
AT_MIDPOINT,
HORIZONTAL,
VERTICAL,
PARALLEL,
PERPENDICULAR,
ORIENTED_SAME,
WHERE_DRAGGED,
COMMENT,
// Analyze
VOLUME,
AREA,
INTERFERENCE,
NAKED_EDGES,
SHOW_DOF,
TRACE_PT,
STOP_TRACING,
STEP_DIM,
// Help
WEBSITE,
ABOUT,
// Recent
RECENT_OPEN = 0xf000,
RECENT_LINK = 0xf100,
};
enum class ContextCommand : uint32_t {
CANCELLED = 0x000,
SUBMENU = 0x001,
SEPARATOR = 0x002,
UNSELECT_ALL = 0x100,
UNSELECT_HOVERED = 0x101,
CUT_SEL = 0x102,
COPY_SEL = 0x103,
PASTE = 0x104,
PASTE_XFRM = 0x105,
DELETE_SEL = 0x106,
SELECT_CHAIN = 0x107,
NEW_CUSTOM_STYLE = 0x110,
NO_STYLE = 0x111,
GROUP_INFO = 0x120,
STYLE_INFO = 0x121,
REFERENCE_DIM = 0x130,
OTHER_ANGLE = 0x131,
DEL_COINCIDENT = 0x132,
SNAP_TO_GRID = 0x140,
REMOVE_SPLINE_PT = 0x141,
ADD_SPLINE_PT = 0x142,
FIRST_STYLE = 0x40000000
};
class TextWindow { class TextWindow {
public: public:
enum { enum {
@ -76,12 +214,12 @@ public:
void MouseLeave(); void MouseLeave();
void ScrollbarEvent(int newPos); void ScrollbarEvent(int newPos);
enum { enum DrawOrHitHow : uint32_t {
PAINT = 0, PAINT = 0,
HOVER = 1, HOVER = 1,
CLICK = 2 CLICK = 2
}; };
void DrawOrHitTestIcons(int how, double mx, double my); void DrawOrHitTestIcons(DrawOrHitHow how, double mx, double my);
void TimerCallback(); void TimerCallback();
Point2d oldMousePos; Point2d oldMousePos;
HideShowIcon *hoveredIcon, *tooltippedIcon; HideShowIcon *hoveredIcon, *tooltippedIcon;
@ -90,7 +228,7 @@ public:
uint8_t *HsvPattern2d(); uint8_t *HsvPattern2d();
uint8_t *HsvPattern1d(double h, double s); uint8_t *HsvPattern1d(double h, double s);
void ColorPickerDone(); void ColorPickerDone();
bool DrawOrHitTestColorPicker(int how, bool leftDown, double x, double y); bool DrawOrHitTestColorPicker(DrawOrHitHow how, bool leftDown, double x, double y);
void Init(); void Init();
void MakeColorTable(const Color *in, float *out); void MakeColorTable(const Color *in, float *out);
@ -100,20 +238,20 @@ public:
void Show(); void Show();
// State for the screen that we are showing in the text window. // State for the screen that we are showing in the text window.
enum { enum class Screen : uint32_t {
SCREEN_LIST_OF_GROUPS = 0, LIST_OF_GROUPS = 0,
SCREEN_GROUP_INFO = 1, GROUP_INFO = 1,
SCREEN_GROUP_SOLVE_INFO = 2, GROUP_SOLVE_INFO = 2,
SCREEN_CONFIGURATION = 3, CONFIGURATION = 3,
SCREEN_STEP_DIMENSION = 4, STEP_DIMENSION = 4,
SCREEN_LIST_OF_STYLES = 5, LIST_OF_STYLES = 5,
SCREEN_STYLE_INFO = 6, STYLE_INFO = 6,
SCREEN_PASTE_TRANSFORMED = 7, PASTE_TRANSFORMED = 7,
SCREEN_EDIT_VIEW = 8, EDIT_VIEW = 8,
SCREEN_TANGENT_ARC = 9 TANGENT_ARC = 9
}; };
typedef struct { typedef struct {
int screen; Screen screen;
hGroup group; hGroup group;
hStyle style; hStyle style;
@ -133,61 +271,61 @@ public:
} ShownState; } ShownState;
ShownState shown; ShownState shown;
enum { enum class Edit : uint32_t {
EDIT_NOTHING = 0, NOTHING = 0,
// For multiple groups // For multiple groups
EDIT_TIMES_REPEATED = 1, TIMES_REPEATED = 1,
EDIT_GROUP_NAME = 2, GROUP_NAME = 2,
EDIT_GROUP_SCALE = 3, GROUP_SCALE = 3,
EDIT_GROUP_COLOR = 4, GROUP_COLOR = 4,
EDIT_GROUP_OPACITY = 5, GROUP_OPACITY = 5,
// For the configuraiton screen // For the configuraiton screen
EDIT_LIGHT_DIRECTION = 100, LIGHT_DIRECTION = 100,
EDIT_LIGHT_INTENSITY = 101, LIGHT_INTENSITY = 101,
EDIT_COLOR = 102, COLOR = 102,
EDIT_CHORD_TOLERANCE = 103, CHORD_TOLERANCE = 103,
EDIT_MAX_SEGMENTS = 104, MAX_SEGMENTS = 104,
EDIT_CAMERA_TANGENT = 105, CAMERA_TANGENT = 105,
EDIT_GRID_SPACING = 106, GRID_SPACING = 106,
EDIT_DIGITS_AFTER_DECIMAL = 107, DIGITS_AFTER_DECIMAL = 107,
EDIT_EXPORT_SCALE = 108, EXPORT_SCALE = 108,
EDIT_EXPORT_OFFSET = 109, EXPORT_OFFSET = 109,
EDIT_CANVAS_SIZE = 110, CANVAS_SIZE = 110,
EDIT_G_CODE_DEPTH = 120, G_CODE_DEPTH = 120,
EDIT_G_CODE_PASSES = 121, G_CODE_PASSES = 121,
EDIT_G_CODE_FEED = 122, G_CODE_FEED = 122,
EDIT_G_CODE_PLUNGE_FEED = 123, G_CODE_PLUNGE_FEED = 123,
EDIT_AUTOSAVE_INTERVAL = 124, AUTOSAVE_INTERVAL = 124,
// For TTF text // For TTF text
EDIT_TTF_TEXT = 300, TTF_TEXT = 300,
// For the step dimension screen // For the step dimension screen
EDIT_STEP_DIM_FINISH = 400, STEP_DIM_FINISH = 400,
EDIT_STEP_DIM_STEPS = 401, STEP_DIM_STEPS = 401,
// For the styles stuff // For the styles stuff
EDIT_STYLE_WIDTH = 500, STYLE_WIDTH = 500,
EDIT_STYLE_TEXT_HEIGHT = 501, STYLE_TEXT_HEIGHT = 501,
EDIT_STYLE_TEXT_ANGLE = 502, STYLE_TEXT_ANGLE = 502,
EDIT_STYLE_COLOR = 503, STYLE_COLOR = 503,
EDIT_STYLE_FILL_COLOR = 504, STYLE_FILL_COLOR = 504,
EDIT_STYLE_NAME = 505, STYLE_NAME = 505,
EDIT_BACKGROUND_COLOR = 506, BACKGROUND_COLOR = 506,
EDIT_BACKGROUND_IMG_SCALE = 507, BACKGROUND_IMG_SCALE = 507,
EDIT_STYLE_STIPPLE_PERIOD = 508, STYLE_STIPPLE_PERIOD = 508,
// For paste transforming // For paste transforming
EDIT_PASTE_TIMES_REPEATED = 600, PASTE_TIMES_REPEATED = 600,
EDIT_PASTE_ANGLE = 601, PASTE_ANGLE = 601,
EDIT_PASTE_SCALE = 602, PASTE_SCALE = 602,
// For view // For view
EDIT_VIEW_SCALE = 700, VIEW_SCALE = 700,
EDIT_VIEW_ORIGIN = 701, VIEW_ORIGIN = 701,
EDIT_VIEW_PROJ_RIGHT = 702, VIEW_PROJ_RIGHT = 702,
EDIT_VIEW_PROJ_UP = 703, VIEW_PROJ_UP = 703,
// For tangent arc // For tangent arc
EDIT_TANGENT_ARC_RADIUS = 800 TANGENT_ARC_RADIUS = 800
}; };
struct { struct {
bool showAgain; bool showAgain;
int meaning; Edit meaning;
int i; int i;
hGroup group; hGroup group;
hRequest request; hRequest request;
@ -231,7 +369,7 @@ public:
// Special screen, based on selection // Special screen, based on selection
void DescribeSelection(); void DescribeSelection();
void GoToScreen(int screen); void GoToScreen(Screen screen);
// All of these are callbacks from the GUI code; first from when // All of these are callbacks from the GUI code; first from when
// we're describing an entity // we're describing an entity
@ -335,110 +473,7 @@ class GraphicsWindow {
public: public:
void Init(); void Init();
// This table describes the top-level menus in the graphics winodw. typedef void MenuHandler(Command id);
typedef enum {
// File
MNU_NEW = 100,
MNU_OPEN,
MNU_OPEN_RECENT,
MNU_SAVE,
MNU_SAVE_AS,
MNU_EXPORT_PNG,
MNU_EXPORT_MESH,
MNU_EXPORT_SURFACES,
MNU_EXPORT_VIEW,
MNU_EXPORT_SECTION,
MNU_EXPORT_WIREFRAME,
MNU_IMPORT,
MNU_EXIT,
// View
MNU_ZOOM_IN,
MNU_ZOOM_OUT,
MNU_ZOOM_TO_FIT,
MNU_SHOW_GRID,
MNU_PERSPECTIVE_PROJ,
MNU_ONTO_WORKPLANE,
MNU_NEAREST_ORTHO,
MNU_NEAREST_ISO,
MNU_CENTER_VIEW,
MNU_SHOW_MENU_BAR,
MNU_SHOW_TOOLBAR,
MNU_SHOW_TEXT_WND,
MNU_UNITS_INCHES,
MNU_UNITS_MM,
MNU_FULL_SCREEN,
// Edit
MNU_UNDO,
MNU_REDO,
MNU_CUT,
MNU_COPY,
MNU_PASTE,
MNU_PASTE_TRANSFORM,
MNU_DELETE,
MNU_SELECT_CHAIN,
MNU_SELECT_ALL,
MNU_SNAP_TO_GRID,
MNU_ROTATE_90,
MNU_UNSELECT_ALL,
MNU_REGEN_ALL,
// Request
MNU_SEL_WORKPLANE,
MNU_FREE_IN_3D,
MNU_DATUM_POINT,
MNU_WORKPLANE,
MNU_LINE_SEGMENT,
MNU_CONSTR_SEGMENT,
MNU_CIRCLE,
MNU_ARC,
MNU_RECTANGLE,
MNU_CUBIC,
MNU_TTF_TEXT,
MNU_SPLIT_CURVES,
MNU_TANGENT_ARC,
MNU_CONSTRUCTION,
// Group
MNU_GROUP_3D,
MNU_GROUP_WRKPL,
MNU_GROUP_EXTRUDE,
MNU_GROUP_LATHE,
MNU_GROUP_ROT,
MNU_GROUP_TRANS,
MNU_GROUP_LINK,
MNU_GROUP_RECENT,
// Constrain
MNU_DISTANCE_DIA,
MNU_REF_DISTANCE,
MNU_ANGLE,
MNU_REF_ANGLE,
MNU_OTHER_ANGLE,
MNU_REFERENCE,
MNU_EQUAL,
MNU_RATIO,
MNU_DIFFERENCE,
MNU_ON_ENTITY,
MNU_SYMMETRIC,
MNU_AT_MIDPOINT,
MNU_HORIZONTAL,
MNU_VERTICAL,
MNU_PARALLEL,
MNU_PERPENDICULAR,
MNU_ORIENTED_SAME,
MNU_WHERE_DRAGGED,
MNU_COMMENT,
// Analyze
MNU_VOLUME,
MNU_AREA,
MNU_INTERFERENCE,
MNU_NAKED_EDGES,
MNU_SHOW_DOF,
MNU_TRACE_PT,
MNU_STOP_TRACING,
MNU_STEP_DIM,
// Help,
MNU_WEBSITE,
MNU_ABOUT
} MenuId;
typedef void MenuHandler(int id);
enum { enum {
ESCAPE_KEY = 27, ESCAPE_KEY = 27,
DELETE_KEY = 127, DELETE_KEY = 127,
@ -448,27 +483,27 @@ public:
SHIFT_MASK = 0x100, SHIFT_MASK = 0x100,
CTRL_MASK = 0x200 CTRL_MASK = 0x200
}; };
enum MenuItemKind { enum class MenuKind : uint32_t {
MENU_ITEM_NORMAL = 0, NORMAL = 0,
MENU_ITEM_CHECK, CHECK,
MENU_ITEM_RADIO RADIO
}; };
typedef struct { typedef struct {
int level; // 0 == on menu bar, 1 == one level down int level; // 0 == on menu bar, 1 == one level down
const char *label; // or NULL for a separator const char *label; // or NULL for a separator
int id; // unique ID Command id; // unique ID
int accel; // keyboard accelerator int accel; // keyboard accelerator
MenuItemKind kind; MenuKind kind;
MenuHandler *fn; MenuHandler *fn;
} MenuEntry; } MenuEntry;
static const MenuEntry menu[]; static const MenuEntry menu[];
static void MenuView(int id); static void MenuView(Command id);
static void MenuEdit(int id); static void MenuEdit(Command id);
static void MenuRequest(int id); static void MenuRequest(Command id);
void DeleteSelection(); void DeleteSelection();
void CopySelection(); void CopySelection();
void PasteClipboard(Vector trans, double theta, double scale); void PasteClipboard(Vector trans, double theta, double scale);
static void MenuClipboard(int id); static void MenuClipboard(Command id);
// The width and height (in pixels) of the window. // The width and height (in pixels) of the window.
double width, height; double width, height;
@ -549,12 +584,6 @@ public:
DRAGGING_MARQUEE = 0x0f000009 DRAGGING_MARQUEE = 0x0f000009
}; };
enum SuggestedConstraint {
SUGGESTED_NONE = 0,
SUGGESTED_HORIZONTAL = Constraint::HORIZONTAL,
SUGGESTED_VERTICAL = Constraint::VERTICAL,
};
struct { struct {
int operation; int operation;
@ -567,19 +596,19 @@ public:
const char *description; const char *description;
SuggestedConstraint suggestion; Constraint::Type suggestion;
} pending; } pending;
void ClearPending(); void ClearPending();
// The constraint that is being edited with the on-screen textbox. // The constraint that is being edited with the on-screen textbox.
hConstraint constraintBeingEdited; hConstraint constraintBeingEdited;
SuggestedConstraint SuggestLineConstraint(hRequest lineSegment); ConstraintBase::Type SuggestLineConstraint(hRequest lineSegment);
Vector SnapToGrid(Vector p); Vector SnapToGrid(Vector p);
bool ConstrainPointByHovered(hEntity pt); bool ConstrainPointByHovered(hEntity pt);
void DeleteTaggedRequests(); void DeleteTaggedRequests();
hRequest AddRequest(int type, bool rememberForUndo); hRequest AddRequest(Request::Type type, bool rememberForUndo);
hRequest AddRequest(int type); hRequest AddRequest(Request::Type type);
class ParametricCurve { class ParametricCurve {
public: public:
@ -666,38 +695,17 @@ public:
void SelectByMarquee(); void SelectByMarquee();
void ClearSuper(); void ClearSuper();
enum {
CMNU_UNSELECT_ALL = 0x100,
CMNU_UNSELECT_HOVERED = 0x101,
CMNU_CUT_SEL = 0x102,
CMNU_COPY_SEL = 0x103,
CMNU_PASTE = 0x104,
CMNU_PASTE_XFRM = 0x105,
CMNU_DELETE_SEL = 0x106,
CMNU_SELECT_CHAIN = 0x107,
CMNU_NEW_CUSTOM_STYLE = 0x110,
CMNU_NO_STYLE = 0x111,
CMNU_GROUP_INFO = 0x120,
CMNU_STYLE_INFO = 0x121,
CMNU_REFERENCE_DIM = 0x130,
CMNU_OTHER_ANGLE = 0x131,
CMNU_DEL_COINCIDENT = 0x132,
CMNU_SNAP_TO_GRID = 0x140,
CMNU_REMOVE_SPLINE_PT = 0x141,
CMNU_ADD_SPLINE_PT = 0x142,
CMNU_FIRST_STYLE = 0x40000000
};
void ContextMenuListStyles(); void ContextMenuListStyles();
int64_t contextMenuCancelTime; int64_t contextMenuCancelTime;
// The toolbar, in toolbar.cpp // The toolbar, in toolbar.cpp
bool ToolbarDrawOrHitTest(int x, int y, bool paint, int *menuHit); bool ToolbarDrawOrHitTest(int x, int y, bool paint, Command *menuHit);
void ToolbarDraw(); void ToolbarDraw();
bool ToolbarMouseMoved(int x, int y); bool ToolbarMouseMoved(int x, int y);
bool ToolbarMouseDown(int x, int y); bool ToolbarMouseDown(int x, int y);
static void TimerCallback(); static void TimerCallback();
int toolbarHovered; Command toolbarHovered;
int toolbarTooltipped; Command toolbarTooltipped;
int toolbarMouseX, toolbarMouseY; int toolbarMouseX, toolbarMouseY;
// This sets what gets displayed. // This sets what gets displayed.

View File

@ -31,8 +31,8 @@ void SolveSpaceUI::UndoRedo() {
} }
void SolveSpaceUI::UndoEnableMenus() { void SolveSpaceUI::UndoEnableMenus() {
EnableMenuById(GraphicsWindow::MNU_UNDO, undo.cnt > 0); EnableMenuByCmd(Command::UNDO, undo.cnt > 0);
EnableMenuById(GraphicsWindow::MNU_REDO, redo.cnt > 0); EnableMenuByCmd(Command::REDO, redo.cnt > 0);
} }
void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) { void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
@ -136,7 +136,7 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
SS.GW.ClearSuper(); SS.GW.ClearSuper();
SS.TW.ClearSuper(); SS.TW.ClearSuper();
SS.ReloadAllImported(); SS.ReloadAllImported();
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL); SS.GenerateAll(SolveSpaceUI::Generate::ALL);
SS.ScheduleShowTW(); SS.ScheduleShowTW();
// Activate the group that was active before. // Activate the group that was active before.

View File

@ -38,7 +38,7 @@ void TextWindow::ShowEditView() {
} }
void TextWindow::ScreenChangeViewScale(int link, uint32_t v) { void TextWindow::ScreenChangeViewScale(int link, uint32_t v) {
SS.TW.edit.meaning = EDIT_VIEW_SCALE; SS.TW.edit.meaning = Edit::VIEW_SCALE;
SS.TW.ShowEditControl(3, ssprintf("%.3f", SS.GW.scale * SS.MmPerUnit())); SS.TW.ShowEditControl(3, ssprintf("%.3f", SS.GW.scale * SS.MmPerUnit()));
} }
@ -49,20 +49,20 @@ void TextWindow::ScreenChangeViewOrigin(int link, uint32_t v) {
SS.MmToString(-SS.GW.offset.y).c_str(), SS.MmToString(-SS.GW.offset.y).c_str(),
SS.MmToString(-SS.GW.offset.z).c_str()); SS.MmToString(-SS.GW.offset.z).c_str());
SS.TW.edit.meaning = EDIT_VIEW_ORIGIN; SS.TW.edit.meaning = Edit::VIEW_ORIGIN;
SS.TW.ShowEditControl(3, edit_value); SS.TW.ShowEditControl(3, edit_value);
} }
void TextWindow::ScreenChangeViewProjection(int link, uint32_t v) { void TextWindow::ScreenChangeViewProjection(int link, uint32_t v) {
std::string edit_value = std::string edit_value =
ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projRight)); ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projRight));
SS.TW.edit.meaning = EDIT_VIEW_PROJ_RIGHT; SS.TW.edit.meaning = Edit::VIEW_PROJ_RIGHT;
SS.TW.ShowEditControl(10, edit_value); SS.TW.ShowEditControl(10, edit_value);
} }
bool TextWindow::EditControlDoneForView(const char *s) { bool TextWindow::EditControlDoneForView(const char *s) {
switch(edit.meaning) { switch(edit.meaning) {
case EDIT_VIEW_SCALE: { case Edit::VIEW_SCALE: {
Expr *e = Expr::From(s, true); Expr *e = Expr::From(s, true);
if(e) { if(e) {
double v = e->Eval() / SS.MmPerUnit(); double v = e->Eval() / SS.MmPerUnit();
@ -75,7 +75,7 @@ bool TextWindow::EditControlDoneForView(const char *s) {
break; break;
} }
case EDIT_VIEW_ORIGIN: { case Edit::VIEW_ORIGIN: {
Vector pt; Vector pt;
if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) { if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) {
pt = pt.ScaledBy(SS.MmPerUnit()); pt = pt.ScaledBy(SS.MmPerUnit());
@ -86,17 +86,17 @@ bool TextWindow::EditControlDoneForView(const char *s) {
break; break;
} }
case EDIT_VIEW_PROJ_RIGHT: case Edit::VIEW_PROJ_RIGHT:
case EDIT_VIEW_PROJ_UP: { case Edit::VIEW_PROJ_UP: {
Vector pt; Vector pt;
if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) { if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) {
Error("Bad format: specify x, y, z"); Error("Bad format: specify x, y, z");
break; break;
} }
if(edit.meaning == EDIT_VIEW_PROJ_RIGHT) { if(edit.meaning == Edit::VIEW_PROJ_RIGHT) {
SS.GW.projRight = pt; SS.GW.projRight = pt;
SS.GW.NormalizeProjectionVectors(); SS.GW.NormalizeProjectionVectors();
edit.meaning = EDIT_VIEW_PROJ_UP; edit.meaning = Edit::VIEW_PROJ_UP;
HideEditControl(); HideEditControl();
ShowEditControl(10, ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projUp)), ShowEditControl(10, ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projUp)),
editControl.halfRow + 2); editControl.halfRow + 2);