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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
#include "solvespace.h"
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) {
@ -15,7 +15,7 @@ void TextWindow::ScreenEditTtfText(int link, uint32_t v) {
Request *r = SK.GetRequest(hr);
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;
}
@ -29,7 +29,7 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
if(gs.entities != 1 || gs.n != 1) return;
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());
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_NUM "(%Fi%3%E, %Fi%3%E, %Fi%3%E)"
switch(e->type) {
case Entity::POINT_IN_3D:
case Entity::POINT_IN_2D:
case Entity::POINT_N_TRANS:
case Entity::POINT_N_ROT_TRANS:
case Entity::POINT_N_COPY:
case Entity::POINT_N_ROT_AA:
case Entity::Type::POINT_IN_3D:
case Entity::Type::POINT_IN_2D:
case Entity::Type::POINT_N_TRANS:
case Entity::Type::POINT_N_ROT_TRANS:
case Entity::Type::POINT_N_COPY:
case Entity::Type::POINT_N_ROT_AA:
p = e->PointGetNum();
Printf(false, "%FtPOINT%E at " PT_AS_STR, COSTR(p));
break;
case Entity::NORMAL_IN_3D:
case Entity::NORMAL_IN_2D:
case Entity::NORMAL_N_COPY:
case Entity::NORMAL_N_ROT:
case Entity::NORMAL_N_ROT_AA: {
case Entity::Type::NORMAL_IN_3D:
case Entity::Type::NORMAL_IN_2D:
case Entity::Type::NORMAL_N_COPY:
case Entity::Type::NORMAL_N_ROT:
case Entity::Type::NORMAL_N_ROT_AA: {
Quaternion q = e->NormalGetNum();
p = q.RotationN();
Printf(false, "%FtNORMAL / COORDINATE SYSTEM%E");
@ -92,7 +92,7 @@ void TextWindow::DescribeSelection() {
Printf(false, " v = " PT_AS_NUM, CO(p));
break;
}
case Entity::WORKPLANE: {
case Entity::Type::WORKPLANE: {
p = SK.GetEntity(e->point[0])->PointGetNum();
Printf(false, "%FtWORKPLANE%E");
Printf(true, " origin = " PT_AS_STR, COSTR(p));
@ -101,7 +101,7 @@ void TextWindow::DescribeSelection() {
Printf(true, " normal = " PT_AS_NUM, CO(p));
break;
}
case Entity::LINE_SEGMENT: {
case Entity::Type::LINE_SEGMENT: {
Vector p0 = SK.GetEntity(e->point[0])->PointGetNum();
p = p0;
Printf(false, "%FtLINE SEGMENT%E");
@ -113,10 +113,10 @@ void TextWindow::DescribeSelection() {
SS.MmToString((p1.Minus(p0).Magnitude())).c_str());
break;
}
case Entity::CUBIC_PERIODIC:
case Entity::CUBIC:
case Entity::Type::CUBIC_PERIODIC:
case Entity::Type::CUBIC:
int pts;
if(e->type == Entity::CUBIC_PERIODIC) {
if(e->type == Entity::Type::CUBIC_PERIODIC) {
Printf(false, "%FtPERIODIC C2 CUBIC SPLINE%E");
pts = (3 + e->extraPoints);
} else if(e->extraPoints > 0) {
@ -132,7 +132,7 @@ void TextWindow::DescribeSelection() {
}
break;
case Entity::ARC_OF_CIRCLE: {
case Entity::Type::ARC_OF_CIRCLE: {
Printf(false, "%FtARC OF A CIRCLE%E");
p = SK.GetEntity(e->point[0])->PointGetNum();
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());
break;
}
case Entity::CIRCLE: {
case Entity::Type::CIRCLE: {
Printf(false, "%FtCIRCLE%E");
p = SK.GetEntity(e->point[0])->PointGetNum();
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());
break;
}
case Entity::FACE_NORMAL_PT:
case Entity::FACE_XPROD:
case Entity::FACE_N_ROT_TRANS:
case Entity::FACE_N_ROT_AA:
case Entity::FACE_N_TRANS:
case Entity::Type::FACE_NORMAL_PT:
case Entity::Type::FACE_XPROD:
case Entity::Type::FACE_N_ROT_TRANS:
case Entity::Type::FACE_N_ROT_AA:
case Entity::Type::FACE_N_TRANS:
Printf(false, "%FtPLANE FACE%E");
p = e->FaceGetNormalNum();
Printf(true, " normal = " PT_AS_NUM, CO(p));
@ -169,7 +169,7 @@ void TextWindow::DescribeSelection() {
Printf(false, " thru = " PT_AS_STR, COSTR(p));
break;
case Entity::TTF_TEXT: {
case Entity::Type::TTF_TEXT: {
Printf(false, "%FtTRUETYPE FONT TEXT%E");
Printf(true, " font = '%Fi%s%E'", e->font.c_str());
if(e->h.isFromRequest()) {
@ -231,9 +231,9 @@ void TextWindow::DescribeSelection() {
Printf(true, " d = %Fi%s", SS.MmToString(d).c_str());
} else if(gs.n == 2 && gs.points == 1 && gs.circlesOrArcs == 1) {
Entity *ec = SK.GetEntity(gs.entity[0]);
if(ec->type == Entity::CIRCLE) {
if(ec->type == Entity::Type::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");
} else ssassert(false, "Unexpected entity type");
Vector p = SK.GetEntity(gs.point[0])->PointGetNum();
@ -321,7 +321,7 @@ void TextWindow::DescribeSelection() {
} else if(gs.n == 0 && gs.constraints == 1) {
Constraint *c = SK.GetConstraint(gs.constraint[0]);
if(c->type == Constraint::DIAMETER) {
if(c->type == Constraint::Type::DIAMETER) {
Printf(false, "%FtDIAMETER CONSTRAINT");
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");
}
if(shown.screen == SCREEN_STYLE_INFO &&
if(shown.screen == Screen::STYLE_INFO &&
shown.style.v >= Style::FIRST_CUSTOM && gs.stylables > 0)
{
// 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++) {
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;
}
}
@ -371,7 +371,7 @@ void TextWindow::DescribeSelection() {
Printf(true, "%Fl%f%Ll(unselect all)%E", &TextWindow::ScreenUnselectAll);
}
void TextWindow::GoToScreen(int screen) {
void TextWindow::GoToScreen(Screen screen) {
shown.screen = screen;
}

View File

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

View File

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

View File

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

View File

@ -119,7 +119,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool wir
if(!out) return;
SS.exportMode = true;
GenerateAll(GENERATE_ALL);
GenerateAll(Generate::ALL);
SMesh *sm = NULL;
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
// to back-facing.
if(SS.GW.showEdges) {
root->MakeCertainEdgesInto(sel, SKdNode::TURNING_EDGES,
root->MakeCertainEdgesInto(sel, EdgeKind::TURNING,
/*coplanarIsInter=*/false, NULL, NULL,
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) {
SS.exportMode = true;
GenerateAll(GENERATE_ALL);
GenerateAll(Generate::ALL);
Group *g = SK.GetGroup(SS.GW.activeGroup);
g->GenerateDisplayItems();

View File

@ -189,39 +189,40 @@ public:
}
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;
// LibreCAD requires the line type to have one of these exact names,
// or otherwise it overwrites it with its own (continuous) style.
type.name = DxfFileWriter::lineTypeName(i);
type.name = DxfFileWriter::lineTypeName(st);
double sw = 1.0;
switch(i) {
case Style::STIPPLE_CONTINUOUS:
switch(st) {
case StipplePattern::CONTINUOUS:
break;
case Style::STIPPLE_DASH:
case StipplePattern::DASH:
type.path.push_back(sw);
type.path.push_back(-sw);
break;
case Style::STIPPLE_LONG_DASH:
case StipplePattern::LONG_DASH:
type.path.push_back(sw * 2.0);
type.path.push_back(-sw);
break;
case Style::STIPPLE_DASH_DOT:
case StipplePattern::DASH_DOT:
type.path.push_back(sw);
type.path.push_back(-sw);
type.path.push_back(0.0);
type.path.push_back(-sw);
break;
case Style::STIPPLE_DOT:
case StipplePattern::DOT:
type.path.push_back(sw);
type.path.push_back(0.0);
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(0.0);
@ -294,7 +295,7 @@ public:
for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) {
if(!writer->NeedToOutput(c)) continue;
switch(c->type) {
case Constraint::PT_PT_DISTANCE: {
case Constraint::Type::PT_PT_DISTANCE: {
Vector ap = SK.GetEntity(c->ptA)->PointGetNum();
Vector bp = SK.GetEntity(c->ptB)->PointGetNum();
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset);
@ -303,7 +304,7 @@ public:
break;
}
case Constraint::PT_LINE_DISTANCE: {
case Constraint::Type::PT_LINE_DISTANCE: {
Vector pt = SK.GetEntity(c->ptA)->PointGetNum();
Entity *line = SK.GetEntity(c->entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
@ -335,7 +336,7 @@ public:
break;
}
case Constraint::DIAMETER: {
case Constraint::Type::DIAMETER: {
Entity *circle = SK.GetEntity(c->entityA);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
@ -359,7 +360,7 @@ public:
break;
}
case Constraint::ANGLE: {
case Constraint::Type::ANGLE: {
Entity *a = SK.GetEntity(c->entityA);
Entity *b = SK.GetEntity(c->entityB);
@ -411,7 +412,7 @@ public:
break;
}
case Constraint::COMMENT: {
case Constraint::Type::COMMENT: {
Style *st = SK.style.FindById(c->GetStyle());
writeText(xfrm(c->disp.offset), c->Label(),
Style::TextHeight(c->GetStyle()) / SS.GW.scale,
@ -627,7 +628,7 @@ public:
}
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;
assignEntityDefaults(&txt, hs);
txt.layer = "text";
@ -638,15 +639,15 @@ public:
txt.height = height;
txt.angle = angle;
txt.alignH = DRW_Text::HCenter;
if(origin & Style::ORIGIN_LEFT) {
if((uint32_t)origin & (uint32_t)Style::TextOrigin::LEFT) {
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.alignV = DRW_Text::VMiddle;
if(origin & Style::ORIGIN_TOP) {
if((uint32_t)origin & (uint32_t)Style::TextOrigin::TOP) {
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;
}
dxf->writeText(&txt);
@ -690,26 +691,26 @@ void DxfFileWriter::FinishAndCloseFile() {
bool DxfFileWriter::NeedToOutput(Constraint *c) {
switch(c->type) {
case Constraint::PT_PT_DISTANCE:
case Constraint::PT_LINE_DISTANCE:
case Constraint::DIAMETER:
case Constraint::ANGLE:
case Constraint::COMMENT:
case Constraint::Type::PT_PT_DISTANCE:
case Constraint::Type::PT_LINE_DISTANCE:
case Constraint::Type::DIAMETER:
case Constraint::Type::ANGLE:
case Constraint::Type::COMMENT:
return c->IsVisible();
}
return false;
}
const char *DxfFileWriter::lineTypeName(int stippleType) {
const char *DxfFileWriter::lineTypeName(StipplePattern stippleType) {
switch(stippleType) {
case Style::STIPPLE_CONTINUOUS: return "CONTINUOUS";
case Style::STIPPLE_DASH: return "DASHED";
case Style::STIPPLE_LONG_DASH: return "DASHEDX2";
case Style::STIPPLE_DASH_DOT: return "DASHDOT";
case Style::STIPPLE_DASH_DOT_DOT: return "DIVIDE";
case Style::STIPPLE_DOT: return "DOT";
case Style::STIPPLE_FREEHAND: return "CONTINUOUS";
case Style::STIPPLE_ZIGZAG: return "CONTINUOUS";
case StipplePattern::CONTINUOUS: return "CONTINUOUS";
case StipplePattern::DASH: return "DASHED";
case StipplePattern::LONG_DASH: return "DASHEDX2";
case StipplePattern::DASH_DOT: return "DASHDOT";
case StipplePattern::DASH_DOT_DOT: return "DIVIDE";
case StipplePattern::DOT: return "DOT";
case StipplePattern::FREEHAND: return "CONTINUOUS";
case StipplePattern::ZIGZAG: return "CONTINUOUS";
}
return "CONTINUOUS";
@ -719,7 +720,7 @@ const char *DxfFileWriter::lineTypeName(int stippleType) {
// 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) {
scale /= 2.0;
@ -729,27 +730,27 @@ static std::string MakeStipplePattern(int pattern, double scale, char delimiter,
std::string result;
switch(pattern) {
case Style::STIPPLE_CONTINUOUS:
case Style::STIPPLE_FREEHAND:
case Style::STIPPLE_ZIGZAG:
case StipplePattern::CONTINUOUS:
case StipplePattern::FREEHAND:
case StipplePattern::ZIGZAG:
return "";
case Style::STIPPLE_DASH:
case StipplePattern::DASH:
result = ssprintf("%.3f_%.3f", scale, scale);
break;
case Style::STIPPLE_DASH_DOT:
case StipplePattern::DASH_DOT:
result = ssprintf("%.3f_%.3f_%.6f_%.3f",
scale, scale * 0.5, zero, scale * 0.5);
break;
case Style::STIPPLE_DASH_DOT_DOT:
case StipplePattern::DASH_DOT_DOT:
result = ssprintf("%.3f_%.3f_%.6f_%.3f_%.6f_%.3f",
scale, scale * 0.5, zero,
scale * 0.5, scale * 0.5, zero);
break;
case Style::STIPPLE_DOT:
case StipplePattern::DOT:
result = ssprintf("%.6f_%.3f", zero, scale * 0.5);
break;
case Style::STIPPLE_LONG_DASH:
case StipplePattern::LONG_DASH:
result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5);
break;
@ -787,7 +788,7 @@ void EpsFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth,
void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth,
bool filled, RgbaColor fillRgb, hStyle hs)
{
int pattern = Style::PatternType(hs);
StipplePattern pattern = Style::PatternType(hs);
double stippleScale = MmToPts(Style::StippleScaleMm(hs));
fprintf(f, " %.3f setlinewidth\r\n"
@ -798,8 +799,7 @@ void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth,
" gsave stroke grestore\r\n",
MmToPts(lineWidth),
strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF(),
MakeStipplePattern(pattern, stippleScale, ' ').c_str()
);
MakeStipplePattern(pattern, stippleScale, ' ').c_str());
if(filled) {
fprintf(f, " %.3f %.3f %.3f setrgbcolor\r\n"
" gsave fill grestore\r\n",
@ -1012,7 +1012,7 @@ void PdfFileWriter::FinishAndCloseFile() {
void PdfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth,
bool filled, RgbaColor fillRgb, hStyle hs)
{
int pattern = Style::PatternType(hs);
StipplePattern pattern = Style::PatternType(hs);
double stippleScale = MmToPts(Style::StippleScaleMm(hs));
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++) {
Style *s = &SK.style.elem[i];
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);
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 *r = AllocExpr();
r->op = PARAM;
r->op = Op::PARAM;
r->parh = p;
return r;
}
@ -249,12 +249,12 @@ Expr *Expr::From(double v) {
}
Expr *r = AllocExpr();
r->op = CONSTANT;
r->op = Op::CONSTANT;
r->v = v;
return r;
}
Expr *Expr::AnyOp(int newOp, Expr *b) {
Expr *Expr::AnyOp(Op newOp, Expr *b) {
Expr *r = AllocExpr();
r->op = newOp;
r->a = this;
@ -264,24 +264,24 @@ Expr *Expr::AnyOp(int newOp, Expr *b) {
int Expr::Children() const {
switch(op) {
case PARAM:
case PARAM_PTR:
case CONSTANT:
case Op::PARAM:
case Op::PARAM_PTR:
case Op::CONSTANT:
return 0;
case PLUS:
case MINUS:
case TIMES:
case DIV:
case Op::PLUS:
case Op::MINUS:
case Op::TIMES:
case Op::DIV:
return 2;
case NEGATE:
case SQRT:
case SQUARE:
case SIN:
case COS:
case ASIN:
case ACOS:
case Op::NEGATE:
case Op::SQRT:
case Op::SQUARE:
case Op::SIN:
case Op::COS:
case Op::ASIN:
case Op::ACOS:
return 1;
default: ssassert(false, "Unexpected operation");
@ -310,17 +310,17 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
IdList<Param,hParam> *thenTry) const
{
Expr *n = AllocExpr();
if(op == PARAM) {
if(op == Op::PARAM) {
// A param that is referenced by its hParam gets rewritten to go
// straight in to the parameter table with a pointer, or simply
// into a constant if it's already known.
Param *p = firstTry->FindByIdNoOops(parh);
if(!p) p = thenTry->FindById(parh);
if(p->known) {
n->op = CONSTANT;
n->op = Op::CONSTANT;
n->v = p->val;
} else {
n->op = PARAM_PTR;
n->op = Op::PARAM_PTR;
n->parp = p;
}
return n;
@ -335,23 +335,23 @@ Expr *Expr::DeepCopyWithParamsAsPointers(IdList<Param,hParam> *firstTry,
double Expr::Eval() const {
switch(op) {
case PARAM: return SK.GetParam(parh)->val;
case PARAM_PTR: return parp->val;
case Op::PARAM: return SK.GetParam(parh)->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 MINUS: return a->Eval() - b->Eval();
case TIMES: return a->Eval() * b->Eval();
case DIV: return a->Eval() / b->Eval();
case Op::PLUS: return a->Eval() + b->Eval();
case Op::MINUS: return a->Eval() - b->Eval();
case Op::TIMES: return a->Eval() * b->Eval();
case Op::DIV: return a->Eval() / b->Eval();
case NEGATE: return -(a->Eval());
case SQRT: return sqrt(a->Eval());
case SQUARE: { double r = a->Eval(); return r*r; }
case SIN: return sin(a->Eval());
case COS: return cos(a->Eval());
case ACOS: return acos(a->Eval());
case ASIN: return asin(a->Eval());
case Op::NEGATE: return -(a->Eval());
case Op::SQRT: return sqrt(a->Eval());
case Op::SQUARE: { double r = a->Eval(); return r*r; }
case Op::SIN: return sin(a->Eval());
case Op::COS: return cos(a->Eval());
case Op::ACOS: return acos(a->Eval());
case Op::ASIN: return asin(a->Eval());
default: ssassert(false, "Unexpected operation");
}
@ -361,38 +361,38 @@ Expr *Expr::PartialWrt(hParam p) const {
Expr *da, *db;
switch(op) {
case PARAM_PTR: return From(p.v == parp->h.v ? 1 : 0);
case PARAM: return From(p.v == parh.v ? 1 : 0);
case Op::PARAM_PTR: return From(p.v == parp->h.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 MINUS: return (a->PartialWrt(p))->Minus(b->PartialWrt(p));
case Op::PLUS: return (a->PartialWrt(p))->Plus(b->PartialWrt(p));
case Op::MINUS: return (a->PartialWrt(p))->Minus(b->PartialWrt(p));
case TIMES:
case Op::TIMES:
da = a->PartialWrt(p);
db = b->PartialWrt(p);
return (a->Times(db))->Plus(b->Times(da));
case DIV:
case Op::DIV:
da = a->PartialWrt(p);
db = b->PartialWrt(p);
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));
case SQUARE:
case Op::SQUARE:
return (From(2.0)->Times(a))->Times(a->PartialWrt(p));
case NEGATE: return (a->PartialWrt(p))->Negate();
case SIN: return (a->Cos())->Times(a->PartialWrt(p));
case COS: return ((a->Sin())->Times(a->PartialWrt(p)))->Negate();
case Op::NEGATE: return (a->PartialWrt(p))->Negate();
case Op::SIN: return (a->Cos())->Times(a->PartialWrt(p));
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()))
->Times(a->PartialWrt(p));
case ACOS:
case Op::ACOS:
return (From(-1)->Div((From(1)->Minus(a->Square()))->Sqrt()))
->Times(a->PartialWrt(p));
@ -402,8 +402,8 @@ Expr *Expr::PartialWrt(hParam p) const {
uint64_t Expr::ParamsUsed() const {
uint64_t r = 0;
if(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) r |= ((uint64_t)1 << (parh.v % 61));
if(op == Op::PARAM_PTR) r |= ((uint64_t)1 << (parp->h.v % 61));
int c = Children();
if(c >= 1) r |= a->ParamsUsed();
@ -412,8 +412,8 @@ uint64_t Expr::ParamsUsed() const {
}
bool Expr::DependsOn(hParam p) const {
if(op == PARAM) return (parh.v == p.v);
if(op == PARAM_PTR) return (parp->h.v == p.v);
if(op == Op::PARAM) return (parh.v == p.v);
if(op == Op::PARAM_PTR) return (parp->h.v == p.v);
int c = Children();
if(c == 1) return a->DependsOn(p);
@ -433,56 +433,56 @@ Expr *Expr::FoldConstants() {
if(c >= 2) n->b = b->FoldConstants();
switch(op) {
case PARAM_PTR:
case PARAM:
case CONSTANT:
case Op::PARAM_PTR:
case Op::PARAM:
case Op::CONSTANT:
break;
case MINUS:
case TIMES:
case DIV:
case PLUS:
case Op::MINUS:
case Op::TIMES:
case Op::DIV:
case Op::PLUS:
// 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();
n->op = CONSTANT;
n->op = Op::CONSTANT;
n->v = nv;
break;
}
// 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;
}
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;
}
// 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;
}
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;
}
// 0*x = x*0 = 0
if(op == TIMES && n->b->op == CONSTANT && Tol(n->b->v, 0)) {
n->op = CONSTANT; n->v = 0; break;
if(op == Op::TIMES && n->b->op == Op::CONSTANT && Tol(n->b->v, 0)) {
n->op = Op::CONSTANT; n->v = 0; break;
}
if(op == TIMES && n->a->op == CONSTANT && Tol(n->a->v, 0)) {
n->op = CONSTANT; n->v = 0; break;
if(op == Op::TIMES && n->a->op == Op::CONSTANT && Tol(n->a->v, 0)) {
n->op = Op::CONSTANT; n->v = 0; break;
}
break;
case SQRT:
case SQUARE:
case NEGATE:
case SIN:
case COS:
case ASIN:
case ACOS:
if(n->a->op == CONSTANT) {
case Op::SQRT:
case Op::SQUARE:
case Op::NEGATE:
case Op::SIN:
case Op::COS:
case Op::ASIN:
case Op::ACOS:
if(n->a->op == Op::CONSTANT) {
double nv = n->Eval();
n->op = CONSTANT;
n->op = Op::CONSTANT;
n->v = nv;
}
break;
@ -493,9 +493,9 @@ Expr *Expr::FoldConstants() {
}
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;
}
int c = Children();
@ -511,14 +511,14 @@ void Expr::Substitute(hParam oldh, hParam newh) {
const hParam Expr::NO_PARAMS = { 0 };
const hParam Expr::MULTIPLE_PARAMS = { 1 };
hParam Expr::ReferencedParams(ParamList *pl) const {
if(op == PARAM) {
if(op == Op::PARAM) {
if(pl->FindByIdNoOops(parh)) {
return parh;
} else {
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();
if(c == 0) {
@ -550,26 +550,26 @@ std::string Expr::Print() const {
char c;
switch(op) {
case PARAM: return ssprintf("param(%08x)", parh.v);
case PARAM_PTR: return ssprintf("param(p%08x)", parp->h.v);
case Op::PARAM: return ssprintf("param(%08x)", parh.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 MINUS: c = '-'; goto p;
case TIMES: c = '*'; goto p;
case DIV: c = '/'; goto p;
case Op::PLUS: c = '+'; goto p;
case Op::MINUS: c = '-'; goto p;
case Op::TIMES: c = '*'; goto p;
case Op::DIV: c = '/'; goto p;
p:
return "(" + a->Print() + " " + c + " " + b->Print() + ")";
break;
case NEGATE: return "(- " + a->Print() + ")";
case SQRT: return "(sqrt " + a->Print() + ")";
case SQUARE: return "(square " + a->Print() + ")";
case SIN: return "(sin " + a->Print() + ")";
case COS: return "(cos " + a->Print() + ")";
case ASIN: return "(asin " + a->Print() + ")";
case ACOS: return "(acos " + a->Print() + ")";
case Op::NEGATE: return "(- " + a->Print() + ")";
case Op::SQRT: return "(sqrt " + a->Print() + ")";
case Op::SQUARE: return "(square " + a->Print() + ")";
case Op::SIN: return "(sin " + a->Print() + ")";
case Op::COS: return "(cos " + a->Print() + ")";
case Op::ASIN: return "(asin " + a->Print() + ")";
case Op::ACOS: return "(acos " + a->Print() + ")";
default: ssassert(false, "Unexpected operation");
}
@ -623,8 +623,8 @@ void Expr::Consume() {
}
int Expr::Precedence(Expr *e) {
if(e->op == ALL_RESOLVED) return -1; // never want to reduce this marker
ssassert(e->op == BINARY_OP || e->op == UNARY_OP, "Unexpected operation");
if(e->op == Op::ALL_RESOLVED) return -1; // never want to reduce this marker
ssassert(e->op == Op::BINARY_OP || e->op == Op::UNARY_OP, "Unexpected operation");
switch(e->c) {
case 'q':
@ -647,12 +647,12 @@ void Expr::Reduce() {
Expr *op = PopOperator();
Expr *n;
int o;
Op o;
switch(op->c) {
case '+': o = PLUS; goto c;
case '-': o = MINUS; goto c;
case '*': o = TIMES; goto c;
case '/': o = DIV; goto c;
case '+': o = Op::PLUS; goto c;
case '-': o = Op::MINUS; goto c;
case '*': o = Op::TIMES; goto c;
case '/': o = Op::DIV; goto c;
c:
b = PopOperand();
a = PopOperand();
@ -678,30 +678,30 @@ void Expr::ReduceAndPush(Expr *n) {
void Expr::Parse() {
Expr *e = AllocExpr();
e->op = ALL_RESOLVED;
e->op = Op::ALL_RESOLVED;
PushOperator(e);
for(;;) {
Expr *n = Next();
if(!n) throw "end of expression unexpected";
if(n->op == CONSTANT) {
if(n->op == Op::CONSTANT) {
PushOperand(n);
Consume();
} else if(n->op == PAREN && n->c == '(') {
} else if(n->op == Op::PAREN && n->c == '(') {
Consume();
Parse();
n = Next();
if(n->op != PAREN || n->c != ')') throw "expected: )";
if(n->op != Op::PAREN || n->c != ')') throw "expected: )";
Consume();
} else if(n->op == UNARY_OP) {
} else if(n->op == Op::UNARY_OP) {
PushOperator(n);
Consume();
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
// unary, depending on context.
n->op = UNARY_OP;
n->op = Op::UNARY_OP;
n->c = 'n';
PushOperator(n);
Consume();
@ -711,7 +711,7 @@ void Expr::Parse() {
}
n = Next();
if(n && n->op == BINARY_OP) {
if(n && n->op == Op::BINARY_OP) {
ReduceAndPush(n);
Consume();
} else {
@ -719,7 +719,7 @@ void Expr::Parse() {
}
}
while(TopOperator()->op != ALL_RESOLVED) {
while(TopOperator()->op != Op::ALL_RESOLVED) {
Reduce();
}
PopOperator(); // discard the ALL_RESOLVED marker
@ -740,7 +740,7 @@ void Expr::Lex(const char *in) {
}
number[len++] = '\0';
Expr *e = AllocExpr();
e->op = CONSTANT;
e->op = Op::CONSTANT;
e->v = atof(number);
Unparsed[UnparsedCnt++] = e;
} else if(isalpha(c) || c == '_') {
@ -754,16 +754,16 @@ void Expr::Lex(const char *in) {
Expr *e = AllocExpr();
if(strcmp(name, "sqrt")==0) {
e->op = UNARY_OP;
e->op = Op::UNARY_OP;
e->c = 'q';
} else if(strcmp(name, "cos")==0) {
e->op = UNARY_OP;
e->op = Op::UNARY_OP;
e->c = 'c';
} else if(strcmp(name, "sin")==0) {
e->op = UNARY_OP;
e->op = Op::UNARY_OP;
e->c = 's';
} else if(strcmp(name, "pi")==0) {
e->op = CONSTANT;
e->op = Op::CONSTANT;
e->v = PI;
} else {
throw "unknown name";
@ -771,7 +771,7 @@ void Expr::Lex(const char *in) {
Unparsed[UnparsedCnt++] = e;
} else if(strchr("+-*/()", c)) {
Expr *e = AllocExpr();
e->op = (c == '(' || c == ')') ? PAREN : BINARY_OP;
e->op = (c == '(' || c == ')') ? Op::PAREN : Op::BINARY_OP;
e->c = c;
Unparsed[UnparsedCnt++] = e;
in++;

View File

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

View File

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

View File

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

View File

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

View File

@ -21,151 +21,150 @@
#define S SHIFT_MASK
#define C CTRL_MASK
#define F(k) (FUNCTION_KEY_BASE+(k))
#define TN MENU_ITEM_NORMAL
#define TC MENU_ITEM_CHECK
#define TR MENU_ITEM_RADIO
#define TN MenuKind::NORMAL
#define TC MenuKind::CHECK
#define TR MenuKind::RADIO
const GraphicsWindow::MenuEntry GraphicsWindow::menu[] = {
//level
// label id accel ty fn
{ 0, "&File", 0, 0, TN, NULL },
{ 1, "&New", MNU_NEW, C|'N', TN, mFile },
{ 1, "&Open...", MNU_OPEN, C|'O', TN, mFile },
{ 1, "Open &Recent", MNU_OPEN_RECENT, 0, TN, mFile },
{ 1, "&Save", MNU_SAVE, C|'S', TN, mFile },
{ 1, "Save &As...", MNU_SAVE_AS, 0, TN, mFile },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Export &Image...", MNU_EXPORT_PNG, 0, TN, mFile },
{ 1, "Export 2d &View...", MNU_EXPORT_VIEW, 0, TN, mFile },
{ 1, "Export 2d &Section...", MNU_EXPORT_SECTION, 0, TN, mFile },
{ 1, "Export 3d &Wireframe...", MNU_EXPORT_WIREFRAME, 0, TN, mFile },
{ 1, "Export Triangle &Mesh...", MNU_EXPORT_MESH, 0, TN, mFile },
{ 1, "Export &Surfaces...", MNU_EXPORT_SURFACES,0, TN, mFile },
{ 1, "Im&port...", MNU_IMPORT ,0, TN, mFile },
{ 0, "&File", Command::NONE, 0, TN, NULL },
{ 1, "&New", Command::NEW, C|'N', TN, mFile },
{ 1, "&Open...", Command::OPEN, C|'O', TN, mFile },
{ 1, "Open &Recent", Command::OPEN_RECENT, 0, TN, mFile },
{ 1, "&Save", Command::SAVE, C|'S', TN, mFile },
{ 1, "Save &As...", Command::SAVE_AS, 0, TN, mFile },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Export &Image...", Command::EXPORT_PNG, 0, TN, mFile },
{ 1, "Export 2d &View...", Command::EXPORT_VIEW, 0, TN, mFile },
{ 1, "Export 2d &Section...", Command::EXPORT_SECTION, 0, TN, mFile },
{ 1, "Export 3d &Wireframe...", Command::EXPORT_WIREFRAME, 0, TN, mFile },
{ 1, "Export Triangle &Mesh...", Command::EXPORT_MESH, 0, TN, mFile },
{ 1, "Export &Surfaces...", Command::EXPORT_SURFACES, 0, TN, mFile },
{ 1, "Im&port...", Command::IMPORT, 0, TN, mFile },
#ifndef __APPLE__
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "E&xit", MNU_EXIT, C|'Q', TN, mFile },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "E&xit", Command::EXIT, C|'Q', TN, mFile },
#endif
{ 0, "&Edit", 0, 0, TN, NULL },
{ 1, "&Undo", MNU_UNDO, C|'Z', TN, mEdit },
{ 1, "&Redo", MNU_REDO, C|'Y', TN, mEdit },
{ 1, "Re&generate All", MNU_REGEN_ALL, ' ', TN, mEdit },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Snap Selection to &Grid", MNU_SNAP_TO_GRID, '.', TN, mEdit },
{ 1, "Rotate Imported &90°", MNU_ROTATE_90, '9', TN, mEdit },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Cu&t", MNU_CUT, C|'X', TN, mClip },
{ 1, "&Copy", MNU_COPY, C|'C', TN, mClip },
{ 1, "&Paste", MNU_PASTE, C|'V', TN, mClip },
{ 1, "Paste &Transformed...", MNU_PASTE_TRANSFORM,C|'T', TN, mClip },
{ 1, "&Delete", MNU_DELETE, DEL, TN, mClip },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Select &Edge Chain", MNU_SELECT_CHAIN, C|'E', TN, mEdit },
{ 1, "Select &All", MNU_SELECT_ALL, C|'A', TN, mEdit },
{ 1, "&Unselect All", MNU_UNSELECT_ALL, ESC, TN, mEdit },
{ 0, "&Edit", Command::NONE, 0, TN, NULL },
{ 1, "&Undo", Command::UNDO, C|'Z', TN, mEdit },
{ 1, "&Redo", Command::REDO, C|'Y', TN, mEdit },
{ 1, "Re&generate All", Command::REGEN_ALL, ' ', TN, mEdit },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Snap Selection to &Grid", Command::SNAP_TO_GRID, '.', TN, mEdit },
{ 1, "Rotate Imported &90°", Command::ROTATE_90, '9', TN, mEdit },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Cu&t", Command::CUT, C|'X', TN, mClip },
{ 1, "&Copy", Command::COPY, C|'C', TN, mClip },
{ 1, "&Paste", Command::PASTE, C|'V', TN, mClip },
{ 1, "Paste &Transformed...", Command::PASTE_TRANSFORM, C|'T', TN, mClip },
{ 1, "&Delete", Command::DELETE, DEL, TN, mClip },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Select &Edge Chain", Command::SELECT_CHAIN, C|'E', TN, mEdit },
{ 1, "Select &All", Command::SELECT_ALL, C|'A', TN, mEdit },
{ 1, "&Unselect All", Command::UNSELECT_ALL, ESC, TN, mEdit },
{ 0, "&View", 0, 0, TN, NULL },
{ 1, "Zoom &In", MNU_ZOOM_IN, '+', TN, mView },
{ 1, "Zoom &Out", MNU_ZOOM_OUT, '-', TN, mView },
{ 1, "Zoom To &Fit", MNU_ZOOM_TO_FIT, 'F', TN, mView },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Align View to &Workplane", MNU_ONTO_WORKPLANE, 'W', TN, mView },
{ 1, "Nearest &Ortho View", MNU_NEAREST_ORTHO, F(2), TN, mView },
{ 1, "Nearest &Isometric View", MNU_NEAREST_ISO, F(3), TN, mView },
{ 1, "&Center View At Point", MNU_CENTER_VIEW, F(4), TN, mView },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Show Snap &Grid", MNU_SHOW_GRID, '>', TC, mView },
{ 1, "Use &Perspective Projection", MNU_PERSPECTIVE_PROJ,'`', TC, mView },
{ 1, NULL, 0, 0, TN, NULL },
{ 0, "&View", Command::NONE, 0, TN, NULL },
{ 1, "Zoom &In", Command::ZOOM_IN, '+', TN, mView },
{ 1, "Zoom &Out", Command::ZOOM_OUT, '-', TN, mView },
{ 1, "Zoom To &Fit", Command::ZOOM_TO_FIT, 'F', TN, mView },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Align View to &Workplane", Command::ONTO_WORKPLANE, 'W', TN, mView },
{ 1, "Nearest &Ortho View", Command::NEAREST_ORTHO, F(2), TN, mView },
{ 1, "Nearest &Isometric View", Command::NEAREST_ISO, F(3), TN, mView },
{ 1, "&Center View At Point", Command::CENTER_VIEW, F(4), TN, mView },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Show Snap &Grid", Command::SHOW_GRID, '>', TC, mView },
{ 1, "Use &Perspective Projection", Command::PERSPECTIVE_PROJ, '`', TC, mView },
{ 1, NULL, Command::NONE, 0, TN, NULL },
#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
{ 1, "Show &Toolbar", MNU_SHOW_TOOLBAR, 0, TC, mView },
{ 1, "Show Property Bro&wser", MNU_SHOW_TEXT_WND, '\t', TC, mView },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Dimensions in &Inches", MNU_UNITS_INCHES, 0, TR, mView },
{ 1, "Dimensions in &Millimeters", MNU_UNITS_MM, 0, TR, mView },
{ 1, "Show &Toolbar", Command::SHOW_TOOLBAR, 0, TC, mView },
{ 1, "Show Property Bro&wser", Command::SHOW_TEXT_WND, '\t', TC, mView },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Dimensions in &Inches", Command::UNITS_INCHES, 0, TR, mView },
{ 1, "Dimensions in &Millimeters", Command::UNITS_MM, 0, TR, mView },
#if defined(HAVE_GTK) || defined(__APPLE__)
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "&Full Screen", MNU_FULL_SCREEN, C|F(11), TC, mView },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Full Screen", Command::FULL_SCREEN, C|F(11), TC, mView },
#endif
{ 0, "&New Group", 0, 0, TN, NULL },
{ 1, "Sketch In &3d", MNU_GROUP_3D, S|'3', TN, mGrp },
{ 1, "Sketch In New &Workplane", MNU_GROUP_WRKPL, S|'W', TN, mGrp },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Step &Translating", MNU_GROUP_TRANS, S|'T', TN, mGrp },
{ 1, "Step &Rotating", MNU_GROUP_ROT, S|'R', TN, mGrp },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "E&xtrude", MNU_GROUP_EXTRUDE, S|'X', TN, mGrp },
{ 1, "&Lathe", MNU_GROUP_LATHE, S|'L', TN, mGrp },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Link / Assemble...", MNU_GROUP_LINK, S|'I', TN, mGrp },
{ 1, "Link Recent", MNU_GROUP_RECENT, 0, TN, mGrp },
{ 0, "&New Group", Command::NONE, 0, TN, NULL },
{ 1, "Sketch In &3d", Command::GROUP_3D, S|'3', TN, mGrp },
{ 1, "Sketch In New &Workplane", Command::GROUP_WRKPL, S|'W', TN, mGrp },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Step &Translating", Command::GROUP_TRANS, S|'T', TN, mGrp },
{ 1, "Step &Rotating", Command::GROUP_ROT, S|'R', TN, mGrp },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "E&xtrude", Command::GROUP_EXTRUDE, S|'X', TN, mGrp },
{ 1, "&Lathe", Command::GROUP_LATHE, S|'L', TN, mGrp },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Link / Assemble...", Command::GROUP_LINK, S|'I', TN, mGrp },
{ 1, "Link Recent", Command::GROUP_RECENT, 0, TN, mGrp },
{ 0, "&Sketch", 0, 0, TN, NULL },
{ 1, "In &Workplane", MNU_SEL_WORKPLANE, '2', TR, mReq },
{ 1, "Anywhere In &3d", MNU_FREE_IN_3D, '3', TR, mReq },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Datum &Point", MNU_DATUM_POINT, 'P', TN, mReq },
{ 1, "&Workplane", MNU_WORKPLANE, 0, TN, mReq },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Line &Segment", MNU_LINE_SEGMENT, 'S', TN, mReq },
{ 1, "C&onstruction Line Segment", MNU_CONSTR_SEGMENT, S|'S', TN, mReq },
{ 1, "&Rectangle", MNU_RECTANGLE, 'R', TN, mReq },
{ 1, "&Circle", MNU_CIRCLE, 'C', TN, mReq },
{ 1, "&Arc of a Circle", MNU_ARC, 'A', TN, mReq },
{ 1, "&Bezier Cubic Spline", MNU_CUBIC, 'B', TN, mReq },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "&Text in TrueType Font", MNU_TTF_TEXT, 'T', TN, mReq },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "To&ggle Construction", MNU_CONSTRUCTION, 'G', TN, mReq },
{ 1, "Tangent &Arc at Point", MNU_TANGENT_ARC, S|'A', TN, mReq },
{ 1, "Split Curves at &Intersection", MNU_SPLIT_CURVES, 'I', TN, mReq },
{ 0, "&Sketch", Command::NONE, 0, TN, NULL },
{ 1, "In &Workplane", Command::SEL_WORKPLANE, '2', TR, mReq },
{ 1, "Anywhere In &3d", Command::FREE_IN_3D, '3', TR, mReq },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Datum &Point", Command::DATUM_POINT, 'P', TN, mReq },
{ 1, "&Workplane", Command::WORKPLANE, 0, TN, mReq },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Line &Segment", Command::LINE_SEGMENT, 'S', TN, mReq },
{ 1, "C&onstruction Line Segment", Command::CONSTR_SEGMENT, S|'S', TN, mReq },
{ 1, "&Rectangle", Command::RECTANGLE, 'R', TN, mReq },
{ 1, "&Circle", Command::CIRCLE, 'C', TN, mReq },
{ 1, "&Arc of a Circle", Command::ARC, 'A', TN, mReq },
{ 1, "&Bezier Cubic Spline", Command::CUBIC, 'B', TN, mReq },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Text in TrueType Font", Command::TTF_TEXT, 'T', TN, mReq },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "To&ggle Construction", Command::CONSTRUCTION, 'G', TN, mReq },
{ 1, "Tangent &Arc at Point", Command::TANGENT_ARC, S|'A', TN, mReq },
{ 1, "Split Curves at &Intersection", Command::SPLIT_CURVES, 'I', TN, mReq },
{ 0, "&Constrain", 0, 0, TN, NULL },
{ 1, "&Distance / Diameter", MNU_DISTANCE_DIA, 'D', TN, mCon },
{ 1, "Re&ference Dimension", MNU_REF_DISTANCE, S|'D', TN, mCon },
{ 1, "A&ngle", MNU_ANGLE, 'N', TN, mCon },
{ 1, "Reference An&gle", MNU_REF_ANGLE, S|'N', TN, mCon },
{ 1, "Other S&upplementary Angle", MNU_OTHER_ANGLE, 'U', TN, mCon },
{ 1, "Toggle R&eference Dim", MNU_REFERENCE, 'E', TN, mCon },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "&Horizontal", MNU_HORIZONTAL, 'H', TN, mCon },
{ 1, "&Vertical", MNU_VERTICAL, 'V', TN, mCon },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "&On Point / Curve / Plane", MNU_ON_ENTITY, 'O', TN, mCon },
{ 1, "E&qual Length / Radius / Angle", MNU_EQUAL, 'Q', TN, mCon },
{ 1, "Length Ra&tio", MNU_RATIO, 'Z', TN, mCon },
{ 1, "Length Diff&erence", MNU_DIFFERENCE, 'J', TN, mCon },
{ 1, "At &Midpoint", MNU_AT_MIDPOINT, 'M', TN, mCon },
{ 1, "S&ymmetric", MNU_SYMMETRIC, 'Y', TN, mCon },
{ 1, "Para&llel / Tangent", MNU_PARALLEL, 'L', TN, mCon },
{ 1, "&Perpendicular", MNU_PERPENDICULAR, '[', TN, mCon },
{ 1, "Same Orient&ation", MNU_ORIENTED_SAME, 'X', TN, mCon },
{ 1, "Lock Point Where &Dragged", MNU_WHERE_DRAGGED, ']', TN, mCon },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Comment", MNU_COMMENT, ';', TN, mCon },
{ 0, "&Constrain", Command::NONE, 0, TN, NULL },
{ 1, "&Distance / Diameter", Command::DISTANCE_DIA, 'D', TN, mCon },
{ 1, "Re&ference Dimension", Command::REF_DISTANCE, S|'D', TN, mCon },
{ 1, "A&ngle", Command::ANGLE, 'N', TN, mCon },
{ 1, "Reference An&gle", Command::REF_ANGLE, S|'N', TN, mCon },
{ 1, "Other S&upplementary Angle", Command::OTHER_ANGLE, 'U', TN, mCon },
{ 1, "Toggle R&eference Dim", Command::REFERENCE, 'E', TN, mCon },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Horizontal", Command::HORIZONTAL, 'H', TN, mCon },
{ 1, "&Vertical", Command::VERTICAL, 'V', TN, mCon },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&On Point / Curve / Plane", Command::ON_ENTITY, 'O', TN, mCon },
{ 1, "E&qual Length / Radius / Angle", Command::EQUAL, 'Q', TN, mCon },
{ 1, "Length Ra&tio", Command::RATIO, 'Z', TN, mCon },
{ 1, "Length Diff&erence", Command::DIFFERENCE, 'J', TN, mCon },
{ 1, "At &Midpoint", Command::AT_MIDPOINT, 'M', TN, mCon },
{ 1, "S&ymmetric", Command::SYMMETRIC, 'Y', TN, mCon },
{ 1, "Para&llel / Tangent", Command::PARALLEL, 'L', TN, mCon },
{ 1, "&Perpendicular", Command::PERPENDICULAR, '[', TN, mCon },
{ 1, "Same Orient&ation", Command::ORIENTED_SAME, 'X', TN, mCon },
{ 1, "Lock Point Where &Dragged", Command::WHERE_DRAGGED, ']', TN, mCon },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Comment", Command::COMMENT, ';', TN, mCon },
{ 0, "&Analyze", 0, 0, TN, NULL },
{ 1, "Measure &Volume", MNU_VOLUME, C|S|'V', TN, mAna },
{ 1, "Measure &Area", MNU_AREA, C|S|'A', TN, mAna },
{ 1, "Show &Interfering Parts", MNU_INTERFERENCE, C|S|'I', TN, mAna },
{ 1, "Show &Naked Edges", MNU_NAKED_EDGES, C|S|'N', TN, mAna },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "Show Degrees of &Freedom", MNU_SHOW_DOF, C|S|'F', TN, mAna },
{ 1, NULL, 0, 0, TN, NULL },
{ 1, "&Trace Point", MNU_TRACE_PT, C|S|'T', TN, mAna },
{ 1, "&Stop Tracing...", MNU_STOP_TRACING, C|S|'S', TN, mAna },
{ 1, "Step &Dimension...", MNU_STEP_DIM, C|S|'D', TN, mAna },
{ 0, "&Analyze", Command::NONE, 0, TN, NULL },
{ 1, "Measure &Volume", Command::VOLUME, C|S|'V', TN, mAna },
{ 1, "Measure &Area", Command::AREA, C|S|'A', TN, mAna },
{ 1, "Show &Interfering Parts", Command::INTERFERENCE, C|S|'I', TN, mAna },
{ 1, "Show &Naked Edges", Command::NAKED_EDGES, C|S|'N', TN, mAna },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "Show Degrees of &Freedom", Command::SHOW_DOF, C|S|'F', TN, mAna },
{ 1, NULL, Command::NONE, 0, TN, NULL },
{ 1, "&Trace Point", Command::TRACE_PT, C|S|'T', TN, mAna },
{ 1, "&Stop Tracing...", Command::STOP_TRACING, C|S|'S', TN, mAna },
{ 1, "Step &Dimension...", Command::STEP_DIM, C|S|'D', TN, mAna },
{ 0, "&Help", 0, 0, TN, NULL },
{ 1, "&Website / Manual", MNU_WEBSITE, 0, TN, mHelp },
{ 0, "&Help", Command::NONE, 0, TN, NULL },
{ 1, "&Website / Manual", Command::WEBSITE, 0, TN, mHelp },
#ifndef __APPLE__
{ 1, "&About", MNU_ABOUT, 0, TN, mHelp },
{ 1, "&About", Command::ABOUT, 0, TN, mHelp },
#endif
{ -1, 0, 0, 0, TN, 0 }
{ -1, 0, Command::NONE, 0, TN, 0 }
};
#undef DEL
@ -321,7 +320,7 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
for(Entity *e : entities) {
if(e->IsPoint()) {
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,
// but circles are particularly bad. We want to get things halfway
// 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) {
case MNU_ZOOM_IN:
case Command::ZOOM_IN:
SS.GW.scale *= 1.2;
SS.ScheduleShowTW();
break;
case MNU_ZOOM_OUT:
case Command::ZOOM_OUT:
SS.GW.scale /= 1.2;
SS.ScheduleShowTW();
break;
case MNU_ZOOM_TO_FIT:
case Command::ZOOM_TO_FIT:
SS.GW.ZoomToFit(/*includingInvisibles=*/false, /*useSelection=*/true);
SS.ScheduleShowTW();
break;
case MNU_SHOW_GRID:
case Command::SHOW_GRID:
SS.GW.showSnapGrid = !SS.GW.showSnapGrid;
if(SS.GW.showSnapGrid && !SS.GW.LockedInWorkplane()) {
Message("No workplane is active, so the grid will not "
@ -472,7 +471,7 @@ void GraphicsWindow::MenuView(int id) {
InvalidateGraphics();
break;
case MNU_PERSPECTIVE_PROJ:
case Command::PERSPECTIVE_PROJ:
SS.usePerspectiveProj = !SS.usePerspectiveProj;
if(SS.cameraTangent < 1e-6) {
Error("The perspective factor is set to zero, so the view will "
@ -485,15 +484,15 @@ void GraphicsWindow::MenuView(int id) {
InvalidateGraphics();
break;
case MNU_ONTO_WORKPLANE:
case Command::ONTO_WORKPLANE:
if(SS.GW.LockedInWorkplane()) {
SS.GW.AnimateOntoWorkplane();
SS.GW.ClearSuper();
SS.ScheduleShowTW();
break;
} // if not in 2d mode fall through and use ORTHO logic
case MNU_NEAREST_ORTHO:
case MNU_NEAREST_ISO: {
case Command::NEAREST_ORTHO:
case Command::NEAREST_ISO: {
static const Vector ortho[3] = {
Vector::From(1, 0, 0),
Vector::From(0, 1, 0),
@ -517,7 +516,7 @@ void GraphicsWindow::MenuView(int id) {
Vector on = ou.Cross(ov);
Vector u, v;
if(id == MNU_NEAREST_ORTHO || id == MNU_ONTO_WORKPLANE) {
if(id == Command::NEAREST_ORTHO || id == Command::ONTO_WORKPLANE) {
u = ou;
v = ov;
} else {
@ -547,7 +546,7 @@ void GraphicsWindow::MenuView(int id) {
break;
}
case MNU_CENTER_VIEW:
case Command::CENTER_VIEW:
SS.GW.GroupSelection();
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
Quaternion quat0;
@ -562,36 +561,36 @@ void GraphicsWindow::MenuView(int id) {
}
break;
case MNU_SHOW_MENU_BAR:
case Command::SHOW_MENU_BAR:
ToggleMenuBar();
SS.GW.EnsureValidActives();
InvalidateGraphics();
break;
case MNU_SHOW_TOOLBAR:
case Command::SHOW_TOOLBAR:
SS.showToolbar = !SS.showToolbar;
SS.GW.EnsureValidActives();
InvalidateGraphics();
break;
case MNU_SHOW_TEXT_WND:
case Command::SHOW_TEXT_WND:
SS.GW.showTextWindow = !SS.GW.showTextWindow;
SS.GW.EnsureValidActives();
break;
case MNU_UNITS_INCHES:
SS.viewUnits = SolveSpaceUI::UNIT_INCHES;
case Command::UNITS_INCHES:
SS.viewUnits = Unit::INCHES;
SS.ScheduleShowTW();
SS.GW.EnsureValidActives();
break;
case MNU_UNITS_MM:
SS.viewUnits = SolveSpaceUI::UNIT_MM;
case Command::UNITS_MM:
SS.viewUnits = Unit::MM;
SS.ScheduleShowTW();
SS.GW.EnsureValidActives();
break;
case MNU_FULL_SCREEN:
case Command::FULL_SCREEN:
ToggleFullScreen();
SS.GW.EnsureValidActives();
break;
@ -622,7 +621,7 @@ void GraphicsWindow::EnsureValidActives() {
activeGroup = SS.CreateDefaultDrawingGroup();
// 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".
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL);
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
} else {
activeGroup = SK.groupOrder.elem[i];
}
@ -649,33 +648,33 @@ void GraphicsWindow::EnsureValidActives() {
// And update the checked state for various menus
bool locked = LockedInWorkplane();
RadioMenuById(MNU_FREE_IN_3D, !locked);
RadioMenuById(MNU_SEL_WORKPLANE, locked);
RadioMenuByCmd(Command::FREE_IN_3D, !locked);
RadioMenuByCmd(Command::SEL_WORKPLANE, locked);
SS.UndoEnableMenus();
switch(SS.viewUnits) {
case SolveSpaceUI::UNIT_MM:
case SolveSpaceUI::UNIT_INCHES:
case Unit::MM:
case Unit::INCHES:
break;
default:
SS.viewUnits = SolveSpaceUI::UNIT_MM;
SS.viewUnits = Unit::MM;
break;
}
RadioMenuById(MNU_UNITS_MM, SS.viewUnits == SolveSpaceUI::UNIT_MM);
RadioMenuById(MNU_UNITS_INCHES, SS.viewUnits == SolveSpaceUI::UNIT_INCHES);
RadioMenuByCmd(Command::UNITS_MM, SS.viewUnits == Unit::MM);
RadioMenuByCmd(Command::UNITS_INCHES, SS.viewUnits == Unit::INCHES);
ShowTextWindow(SS.GW.showTextWindow);
CheckMenuById(MNU_SHOW_TEXT_WND, SS.GW.showTextWindow);
CheckMenuByCmd(Command::SHOW_TEXT_WND, SS.GW.showTextWindow);
#if defined(__APPLE__)
CheckMenuById(MNU_SHOW_MENU_BAR, MenuBarIsVisible());
CheckMenuByCmd(Command::SHOW_MENU_BAR, MenuBarIsVisible());
#endif
CheckMenuById(MNU_SHOW_TOOLBAR, SS.showToolbar);
CheckMenuById(MNU_PERSPECTIVE_PROJ, SS.usePerspectiveProj);
CheckMenuById(MNU_SHOW_GRID, SS.GW.showSnapGrid);
CheckMenuByCmd(Command::SHOW_TOOLBAR, SS.showToolbar);
CheckMenuByCmd(Command::PERSPECTIVE_PROJ, SS.usePerspectiveProj);
CheckMenuByCmd(Command::SHOW_GRID, SS.GW.showSnapGrid);
#if defined(HAVE_GTK) || defined(__APPLE__)
CheckMenuById(MNU_FULL_SCREEN, FullScreenIsActive());
CheckMenuByCmd(Command::FULL_SCREEN, FullScreenIsActive());
#endif
if(change) SS.ScheduleShowTW();
@ -699,7 +698,7 @@ bool GraphicsWindow::LockedInWorkplane() {
void GraphicsWindow::ForceTextWindowShown() {
if(!showTextWindow) {
showTextWindow = true;
CheckMenuById(MNU_SHOW_TEXT_WND, true);
CheckMenuByCmd(Command::SHOW_TEXT_WND, true);
ShowTextWindow(true);
}
}
@ -723,7 +722,7 @@ void GraphicsWindow::DeleteTaggedRequests() {
ClearSuper();
// And regenerate to get rid of what it generates, plus anything
// that references it (since the regen code checks for that).
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL);
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
EnsureValidActives();
SS.ScheduleShowTW();
}
@ -746,9 +745,9 @@ Vector GraphicsWindow::SnapToGrid(Vector p) {
return pp.ScaleOutOfCsys(wu, wv, wn).Plus(wo);
}
void GraphicsWindow::MenuEdit(int id) {
void GraphicsWindow::MenuEdit(Command id) {
switch(id) {
case MNU_UNSELECT_ALL:
case Command::UNSELECT_ALL:
SS.GW.GroupSelection();
// If there's nothing selected to de-select, and no operation
// to cancel, then perhaps they want to return to the home
@ -760,8 +759,8 @@ void GraphicsWindow::MenuEdit(int id) {
if(!(TextEditControlIsVisible() ||
GraphicsEditControlIsVisible()))
{
if(SS.TW.shown.screen == TextWindow::SCREEN_STYLE_INFO) {
SS.TW.GoToScreen(TextWindow::SCREEN_LIST_OF_STYLES);
if(SS.TW.shown.screen == TextWindow::Screen::STYLE_INFO) {
SS.TW.GoToScreen(TextWindow::Screen::LIST_OF_STYLES);
} else {
SS.TW.ClearSuper();
}
@ -779,11 +778,11 @@ void GraphicsWindow::MenuEdit(int id) {
}
if(SS.exportMode) {
SS.exportMode = false;
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL);
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
}
break;
case MNU_SELECT_ALL: {
case Command::SELECT_ALL: {
Entity *e;
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
if(e->group.v != SS.GW.activeGroup.v) continue;
@ -797,7 +796,7 @@ void GraphicsWindow::MenuEdit(int id) {
break;
}
case MNU_SELECT_CHAIN: {
case Command::SELECT_CHAIN: {
Entity *e;
int newlySelected = 0;
bool didSomething;
@ -847,7 +846,7 @@ void GraphicsWindow::MenuEdit(int id) {
break;
}
case MNU_ROTATE_90: {
case Command::ROTATE_90: {
SS.GW.GroupSelection();
Entity *e = NULL;
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;
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 "
"entity from an linked part, or make a link "
"group the active group.");
@ -883,7 +882,7 @@ void GraphicsWindow::MenuEdit(int id) {
break;
}
case MNU_SNAP_TO_GRID: {
case Command::SNAP_TO_GRID: {
if(!SS.GW.LockedInWorkplane()) {
Error("No workplane is active. Select a workplane to define "
"the plane for the snap grid.");
@ -924,17 +923,17 @@ void GraphicsWindow::MenuEdit(int id) {
break;
}
case MNU_UNDO:
case Command::UNDO:
SS.UndoUndo();
break;
case MNU_REDO:
case Command::REDO:
SS.UndoRedo();
break;
case MNU_REGEN_ALL:
case Command::REGEN_ALL:
SS.ReloadAllImported();
SS.GenerateAll(SolveSpaceUI::GENERATE_UNTIL_ACTIVE);
SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE);
SS.ScheduleShowTW();
break;
@ -942,17 +941,17 @@ void GraphicsWindow::MenuEdit(int id) {
}
}
void GraphicsWindow::MenuRequest(int id) {
void GraphicsWindow::MenuRequest(Command id) {
const char *s;
switch(id) {
case MNU_SEL_WORKPLANE: {
case Command::SEL_WORKPLANE: {
SS.GW.GroupSelection();
Group *g = SK.GetGroup(SS.GW.activeGroup);
if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) {
// A user-selected workplane
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
g->activeWorkplane = g->h.entity(0);
Message("No workplane selected. Activating default workplane "
@ -972,14 +971,14 @@ void GraphicsWindow::MenuRequest(int id) {
SS.ScheduleShowTW();
break;
}
case MNU_FREE_IN_3D:
case Command::FREE_IN_3D:
SS.GW.SetWorkplaneFreeIn3d();
SS.GW.EnsureValidActives();
SS.ScheduleShowTW();
InvalidateGraphics();
break;
case MNU_TANGENT_ARC:
case Command::TANGENT_ARC:
SS.GW.GroupSelection();
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
SS.GW.MakeTangentArc();
@ -988,30 +987,30 @@ void GraphicsWindow::MenuRequest(int id) {
"single point, or select nothing to set up arc "
"parameters.");
} else {
SS.TW.GoToScreen(TextWindow::SCREEN_TANGENT_ARC);
SS.TW.GoToScreen(TextWindow::Screen::TANGENT_ARC);
SS.GW.ForceTextWindowShown();
SS.ScheduleShowTW();
InvalidateGraphics(); // repaint toolbar
}
break;
case MNU_ARC: s = "click point on arc (draws anti-clockwise)"; goto c;
case MNU_DATUM_POINT: s = "click to place datum point"; goto c;
case MNU_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 MNU_CUBIC: s = "click first point of cubic segment"; goto c;
case MNU_CIRCLE: s = "click center of circle"; goto c;
case MNU_WORKPLANE: s = "click origin of workplane"; goto c;
case MNU_RECTANGLE: s = "click one corner of rectangle"; goto c;
case MNU_TTF_TEXT: s = "click top left of text"; goto c;
case Command::ARC: s = "click point on arc (draws anti-clockwise)"; goto c;
case Command::DATUM_POINT: s = "click to place datum point"; goto c;
case Command::LINE_SEGMENT: s = "click first point of line segment"; goto c;
case Command::CONSTR_SEGMENT: s = "click first point of construction line segment"; goto c;
case Command::CUBIC: s = "click first point of cubic segment"; goto c;
case Command::CIRCLE: s = "click center of circle"; goto c;
case Command::WORKPLANE: s = "click origin of workplane"; goto c;
case Command::RECTANGLE: s = "click one corner of rectangle"; goto c;
case Command::TTF_TEXT: s = "click top left of text"; goto c;
c:
SS.GW.pending.operation = id;
SS.GW.pending.operation = (uint32_t)id;
SS.GW.pending.description = s;
SS.ScheduleShowTW();
InvalidateGraphics(); // repaint toolbar
break;
case MNU_CONSTRUCTION: {
case Command::CONSTRUCTION: {
SS.UndoRemember();
SS.GW.GroupSelection();
if(SS.GW.gs.entities == 0) {
@ -1031,7 +1030,7 @@ c:
break;
}
case MNU_SPLIT_CURVES:
case Command::SPLIT_CURVES:
SS.GW.SplitLinesOrCurves();
break;
@ -1063,7 +1062,7 @@ void GraphicsWindow::ToggleBool(bool *v) {
SS.ScheduleShowTW();
}
GraphicsWindow::SuggestedConstraint GraphicsWindow::SuggestLineConstraint(hRequest request) {
Constraint::Type GraphicsWindow::SuggestLineConstraint(hRequest request) {
if(LockedInWorkplane()) {
Entity *ptA = SK.GetEntity(request.entity(1)),
*ptB = SK.GetEntity(request.entity(2));
@ -1078,12 +1077,12 @@ GraphicsWindow::SuggestedConstraint GraphicsWindow::SuggestLineConstraint(hReque
const double TOLERANCE_RATIO = 0.02;
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)
return SUGGESTED_HORIZONTAL;
return Constraint::Type::HORIZONTAL;
else
return SUGGESTED_NONE;
return Constraint::Type::UNKNOWN;
} 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;
}
void Group::MenuGroup(int id) {
void Group::MenuGroup(Command id) {
Group g = {};
g.visible = true;
g.color = RGBi(100, 100, 100);
g.scale = 1;
if(id >= RECENT_LINK && id < (RECENT_LINK + MAX_RECENT)) {
g.linkFile = RecentFile[id-RECENT_LINK];
id = GraphicsWindow::MNU_GROUP_LINK;
if((uint32_t)id >= (uint32_t)Command::RECENT_LINK &&
(uint32_t)id < ((uint32_t)Command::RECENT_LINK + MAX_RECENT)) {
g.linkFile = RecentFile[(uint32_t)id-(uint32_t)Command::RECENT_LINK];
id = Command::GROUP_LINK;
}
SS.GW.GroupSelection();
switch(id) {
case GraphicsWindow::MNU_GROUP_3D:
g.type = DRAWING_3D;
case Command::GROUP_3D:
g.type = Type::DRAWING_3D;
g.name = "sketch-in-3d";
break;
case GraphicsWindow::MNU_GROUP_WRKPL:
g.type = DRAWING_WORKPLANE;
case Command::GROUP_WRKPL:
g.type = Type::DRAWING_WORKPLANE;
g.name = "sketch-in-plane";
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;
u = u.ClosestOrtho();
@ -104,7 +105,7 @@ void Group::MenuGroup(int id) {
g.predef.q = Quaternion::From(u, v);
g.predef.origin = gs.point[0];
} 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.entityB = gs.entity[0];
@ -132,21 +133,21 @@ void Group::MenuGroup(int id) {
}
break;
case GraphicsWindow::MNU_GROUP_EXTRUDE:
case Command::GROUP_EXTRUDE:
if(!SS.GW.LockedInWorkplane()) {
Error("Select a workplane (Sketch -> In Workplane) before "
"extruding. The sketch will be extruded normal to the "
"workplane.");
return;
}
g.type = EXTRUDE;
g.type = Type::EXTRUDE;
g.opA = SS.GW.activeGroup;
g.predef.entityB = SS.GW.ActiveWorkplane();
g.subtype = ONE_SIDED;
g.subtype = Subtype::ONE_SIDED;
g.name = "extrude";
break;
case GraphicsWindow::MNU_GROUP_LATHE:
case Command::GROUP_LATHE:
if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) {
g.predef.origin = gs.point[0];
g.predef.entityB = gs.vector[0];
@ -163,12 +164,12 @@ void Group::MenuGroup(int id) {
" * a line segment (revolved about line segment)\n");
return;
}
g.type = LATHE;
g.type = Type::LATHE;
g.opA = SS.GW.activeGroup;
g.name = "lathe";
break;
case GraphicsWindow::MNU_GROUP_ROT: {
case Command::GROUP_ROT: {
if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) {
g.predef.origin = gs.point[0];
Entity *w = SK.GetEntity(SS.GW.ActiveWorkplane());
@ -187,26 +188,26 @@ void Group::MenuGroup(int id) {
"line / normal)\n");
return;
}
g.type = ROTATE;
g.type = Type::ROTATE;
g.opA = SS.GW.activeGroup;
g.valA = 3;
g.subtype = ONE_SIDED;
g.subtype = Subtype::ONE_SIDED;
g.name = "rotate";
break;
}
case GraphicsWindow::MNU_GROUP_TRANS:
g.type = TRANSLATE;
case Command::GROUP_TRANS:
g.type = Type::TRANSLATE;
g.opA = SS.GW.activeGroup;
g.valA = 3;
g.subtype = ONE_SIDED;
g.subtype = Subtype::ONE_SIDED;
g.predef.entityB = SS.GW.ActiveWorkplane();
g.activeWorkplane = SS.GW.ActiveWorkplane();
g.name = "translate";
break;
case GraphicsWindow::MNU_GROUP_LINK: {
g.type = LINKED;
case Command::GROUP_LINK: {
g.type = Type::LINKED;
if(g.linkFile.empty()) {
if(!GetOpenFile(&g.linkFile, "", SlvsFileFilter)) return;
}
@ -237,7 +238,7 @@ void Group::MenuGroup(int id) {
g.name = "link";
}
g.meshCombine = COMBINE_AS_ASSEMBLE;
g.meshCombine = CombineAs::ASSEMBLE;
break;
}
@ -269,13 +270,13 @@ void Group::MenuGroup(int id) {
SK.group.AddAndAssignId(&g);
Group *gg = SK.GetGroup(g.h);
if(gg->type == LINKED) {
if(gg->type == Type::LINKED) {
SS.ReloadAllImported();
}
gg->clean = false;
SS.GW.activeGroup = gg->h;
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
// regenerated, because the workplane doesn't exist until then.
gg->activeWorkplane = gg->h.entity(0);
@ -287,7 +288,7 @@ void Group::MenuGroup(int id) {
}
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;
tx = h.param(0);
@ -323,7 +324,8 @@ std::string Group::DescriptionString() {
}
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;
} else {
SS.GW.showFaces = false;
@ -343,12 +345,12 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
gp = gp.WithMagnitude(200/SS.GW.scale);
int a, i;
switch(type) {
case DRAWING_3D:
case Type::DRAWING_3D:
break;
case DRAWING_WORKPLANE: {
case Type::DRAWING_WORKPLANE: {
Quaternion q;
if(subtype == WORKPLANE_BY_LINE_SEGMENTS) {
if(subtype == Subtype::WORKPLANE_BY_LINE_SEGMENTS) {
Vector u = SK.GetEntity(predef.entityB)->VectorGetNum();
Vector v = SK.GetEntity(predef.entityC)->VectorGetNum();
u = u.WithMagnitude(1);
@ -359,13 +361,13 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
if(predef.negateU) u = u.ScaledBy(-1);
if(predef.negateV) v = v.ScaledBy(-1);
q = Quaternion::From(u, v);
} else if(subtype == WORKPLANE_BY_POINT_ORTHO) {
} else if(subtype == Subtype::WORKPLANE_BY_POINT_ORTHO) {
// Already given, numerically.
q = predef.q;
} else ssassert(false, "Unexpected workplane subtype");
Entity normal = {};
normal.type = Entity::NORMAL_N_COPY;
normal.type = Entity::Type::NORMAL_N_COPY;
normal.numNormal = q;
normal.point[0] = h.entity(2);
normal.group = h;
@ -373,14 +375,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
entity->Add(&normal);
Entity point = {};
point.type = Entity::POINT_N_COPY;
point.type = Entity::Type::POINT_N_COPY;
point.numPoint = SK.GetEntity(predef.origin)->PointGetNum();
point.group = h;
point.h = h.entity(2);
entity->Add(&point);
Entity wp = {};
wp.type = Entity::WORKPLANE;
wp.type = Entity::Type::WORKPLANE;
wp.normal = normal.h;
wp.point[0] = point.h;
wp.group = h;
@ -389,14 +391,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
break;
}
case EXTRUDE: {
case Type::EXTRUDE: {
AddParam(param, h.param(0), gn.x);
AddParam(param, h.param(1), gn.y);
AddParam(param, h.param(2), gn.z);
int ai, af;
if(subtype == ONE_SIDED) {
if(subtype == Subtype::ONE_SIDED) {
ai = 0; af = 2;
} else if(subtype == TWO_SIDED) {
} else if(subtype == Subtype::TWO_SIDED) {
ai = -1; af = 1;
} else ssassert(false, "Unexpected extrusion subtype");
@ -429,7 +431,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
break;
}
case LATHE: {
case Type::LATHE: {
Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum();
Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum();
@ -470,14 +472,14 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
break;
}
case TRANSLATE: {
case Type::TRANSLATE: {
// The translation vector
AddParam(param, h.param(0), gp.x);
AddParam(param, h.param(1), gp.y);
AddParam(param, h.param(2), gp.z);
int n = (int)valA, a0 = 0;
if(subtype == ONE_SIDED && skipFirst) {
if(subtype == Subtype::ONE_SIDED && skipFirst) {
a0++; n++;
}
@ -488,7 +490,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
e->CalculateNumerical(false);
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,
h.param(0), h.param(1), h.param(2),
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
@ -497,7 +499,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
}
break;
}
case ROTATE: {
case Type::ROTATE: {
// The center of rotation
AddParam(param, h.param(0), gc.x);
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);
int n = (int)valA, a0 = 0;
if(subtype == ONE_SIDED && skipFirst) {
if(subtype == Subtype::ONE_SIDED && skipFirst) {
a0++; n++;
}
@ -520,7 +522,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
e->CalculateNumerical(false);
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,
h.param(0), h.param(1), h.param(2),
h.param(3), h.param(4), h.param(5), h.param(6),
@ -529,7 +531,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
}
break;
}
case LINKED:
case Type::LINKED:
// The translation vector
AddParam(param, h.param(0), gp.x);
AddParam(param, h.param(1), gp.y);
@ -554,8 +556,8 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
}
bool Group::IsSolvedOkay() {
return this->solved.how == System::SOLVED_OKAY ||
(this->allowRedundant && this->solved.how == System::REDUNDANT_OKAY);
return this->solved.how == SolveResult::OKAY ||
(this->allowRedundant && this->solved.how == SolveResult::REDUNDANT_OKAY);
}
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) {
if(type == LINKED) {
if(type == Type::LINKED) {
// Normalize the quaternion
ExprQuaternion q = {
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(6)) };
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
#define EC(x) (Expr::From(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);
#undef EC
#undef EP
} else if(type == EXTRUDE) {
} else if(type == Type::EXTRUDE) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) {
// The extrusion path is locked along a line, normal to the
// specified workplane.
@ -605,7 +607,7 @@ void Group::GenerateEquations(IdList<Equation,hEquation> *l) {
AddEq(l, u.Dot(extruden), 0);
AddEq(l, v.Dot(extruden), 1);
}
} else if(type == TRANSLATE) {
} else if(type == Type::TRANSLATE) {
if(predef.entityB.v != Entity::FREE_IN_3D.v) {
Entity *w = SK.GetEntity(predef.entityB);
ExprVector n = w->Normal()->NormalExprsN();
@ -657,9 +659,9 @@ void Group::MakeExtrusionLines(IdList<Entity,hEntity> *el, hEntity in) {
en.construction = ep->construction;
en.style = ep->style;
en.h = Remap(ep->h, REMAP_PT_TO_LINE);
en.type = Entity::LINE_SEGMENT;
en.type = Entity::Type::LINE_SEGMENT;
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
// original line is a point in the plane, and the line is in the plane.
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.style = ep->style;
en.h = Remap(ep->h, REMAP_LINE_TO_FACE);
en.type = Entity::FACE_XPROD;
en.type = Entity::Type::FACE_XPROD;
el->Add(&en);
}
}
@ -704,7 +706,7 @@ void Group::MakeLatheCircles(IdList<Entity,hEntity> *el, IdList<Param,hParam> *p
en.construction = ep->construction;
en.style = ep->style;
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.
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.group = en.group;
n.style = en.style;
n.type = Entity::NORMAL_N_COPY;
n.type = Entity::Type::NORMAL_N_COPY;
// Create basis for the normal.
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);
en.normal = n.h;
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.
Vector a = SK.GetEntity(ep->point[0])->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.style = ep->style;
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];
el->Add(&en);
}
@ -760,7 +762,7 @@ void Group::MakeExtrusionTopBottomFaces(IdList<Entity,hEntity> *el, hEntity pt)
Vector n = src->polyLoops.normal;
Entity en = {};
en.type = Entity::FACE_NORMAL_PT;
en.type = Entity::Type::FACE_NORMAL_PT;
en.group = h;
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;
switch(ep->type) {
case Entity::WORKPLANE:
case Entity::Type::WORKPLANE:
// Don't copy these.
return;
case Entity::POINT_N_COPY:
case Entity::POINT_N_TRANS:
case Entity::POINT_N_ROT_TRANS:
case Entity::POINT_N_ROT_AA:
case Entity::POINT_IN_3D:
case Entity::POINT_IN_2D:
case Entity::Type::POINT_N_COPY:
case Entity::Type::POINT_N_TRANS:
case Entity::Type::POINT_N_ROT_TRANS:
case Entity::Type::POINT_N_ROT_AA:
case Entity::Type::POINT_IN_3D:
case Entity::Type::POINT_IN_2D:
if(asTrans) {
en.type = Entity::POINT_N_TRANS;
en.type = Entity::Type::POINT_N_TRANS;
en.param[0] = dx;
en.param[1] = dy;
en.param[2] = dz;
} else {
if(asAxisAngle) {
en.type = Entity::POINT_N_ROT_AA;
en.type = Entity::Type::POINT_N_ROT_AA;
} else {
en.type = Entity::POINT_N_ROT_TRANS;
en.type = Entity::Type::POINT_N_ROT_TRANS;
}
en.param[0] = dx;
en.param[1] = dy;
@ -823,18 +825,18 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.numPoint = (ep->actPoint).ScaledBy(scale);
break;
case Entity::NORMAL_N_COPY:
case Entity::NORMAL_N_ROT:
case Entity::NORMAL_N_ROT_AA:
case Entity::NORMAL_IN_3D:
case Entity::NORMAL_IN_2D:
case Entity::Type::NORMAL_N_COPY:
case Entity::Type::NORMAL_N_ROT:
case Entity::Type::NORMAL_N_ROT_AA:
case Entity::Type::NORMAL_IN_3D:
case Entity::Type::NORMAL_IN_2D:
if(asTrans) {
en.type = Entity::NORMAL_N_COPY;
en.type = Entity::Type::NORMAL_N_COPY;
} else {
if(asAxisAngle) {
en.type = Entity::NORMAL_N_ROT_AA;
en.type = Entity::Type::NORMAL_N_ROT_AA;
} else {
en.type = Entity::NORMAL_N_ROT;
en.type = Entity::Type::NORMAL_N_ROT;
}
en.param[0] = qw;
en.param[1] = qvx;
@ -847,27 +849,27 @@ void Group::CopyEntity(IdList<Entity,hEntity> *el,
en.point[0] = Remap(ep->point[0], remap);
break;
case Entity::DISTANCE_N_COPY:
case Entity::DISTANCE:
en.type = Entity::DISTANCE_N_COPY;
case Entity::Type::DISTANCE_N_COPY:
case Entity::Type::DISTANCE:
en.type = Entity::Type::DISTANCE_N_COPY;
en.numDistance = ep->actDistance*fabs(scale);
break;
case Entity::FACE_NORMAL_PT:
case Entity::FACE_XPROD:
case Entity::FACE_N_ROT_TRANS:
case Entity::FACE_N_TRANS:
case Entity::FACE_N_ROT_AA:
case Entity::Type::FACE_NORMAL_PT:
case Entity::Type::FACE_XPROD:
case Entity::Type::FACE_N_ROT_TRANS:
case Entity::Type::FACE_N_TRANS:
case Entity::Type::FACE_N_ROT_AA:
if(asTrans) {
en.type = Entity::FACE_N_TRANS;
en.type = Entity::Type::FACE_N_TRANS;
en.param[0] = dx;
en.param[1] = dy;
en.param[2] = dz;
} else {
if(asAxisAngle) {
en.type = Entity::FACE_N_ROT_AA;
en.type = Entity::Type::FACE_N_ROT_AA;
} else {
en.type = Entity::FACE_N_ROT_TRANS;
en.type = Entity::Type::FACE_N_ROT_TRANS;
}
en.param[0] = dx;
en.param[1] = dy;

View File

@ -58,24 +58,24 @@ void Group::GenerateLoops() {
bezierLoops.Clear();
bezierOpens.Clear();
if(type == DRAWING_3D || type == DRAWING_WORKPLANE ||
type == ROTATE || type == TRANSLATE || type == LINKED)
if(type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE ||
type == Type::ROTATE || type == Type::TRANSLATE || type == Type::LINKED)
{
bool allClosed = false, allCoplanar = false, allNonZeroLen = false;
AssembleLoops(&allClosed, &allCoplanar, &allNonZeroLen);
if(!allNonZeroLen) {
polyError.how = POLY_ZERO_LEN_EDGE;
polyError.how = PolyError::ZERO_LEN_EDGE;
} else if(!allCoplanar) {
polyError.how = POLY_NOT_COPLANAR;
polyError.how = PolyError::NOT_COPLANAR;
} else if(!allClosed) {
polyError.how = POLY_NOT_CLOSED;
polyError.how = PolyError::NOT_CLOSED;
} else {
polyError.how = POLY_GOOD;
polyError.how = PolyError::GOOD;
// The self-intersecting check is kind of slow, so don't run it
// unless requested.
if(SS.checkClosedContour) {
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;
int n = (int)valA, a0 = 0;
if(subtype == ONE_SIDED && skipFirst) {
if(subtype == Subtype::ONE_SIDED && skipFirst) {
a0++; n++;
}
int 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;
T transd = {};
if(type == TRANSLATE) {
if(type == Type::TRANSLATE) {
Vector trans = Vector::From(h.param(0), h.param(1), h.param(2));
trans = trans.ScaledBy(ap);
transd.MakeFromTransformationOf(steps,
@ -157,7 +157,7 @@ void Group::GenerateForStepAndRepeat(T *steps, T *outs) {
}
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
// same as last time, no combining required. Likewise if we have a mesh
// 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
// previous group's shell, using the requested operation.
if(how == COMBINE_AS_UNION) {
if(how == CombineAs::UNION) {
outs->MakeFromUnionOf(prevs, thiss);
} else if(how == COMBINE_AS_DIFFERENCE) {
} else if(how == CombineAs::DIFFERENCE) {
outs->MakeFromDifferenceOf(prevs, thiss);
} else {
outs->MakeFromAssemblyOf(prevs, thiss);
@ -191,26 +191,26 @@ void Group::GenerateShellAndMesh() {
// Don't attempt a lathe or extrusion unless the source section is good:
// planar and not self-intersecting.
bool haveSrc = true;
if(type == EXTRUDE || type == LATHE) {
if(type == Type::EXTRUDE || type == Type::LATHE) {
Group *src = SK.GetGroup(opA);
if(src->polyError.how != POLY_GOOD) {
if(src->polyError.how != PolyError::GOOD) {
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,
// not our own previous group.
srcg = SK.GetGroup(opA);
GenerateForStepAndRepeat<SShell>(&(srcg->thisShell), &thisShell);
GenerateForStepAndRepeat<SMesh> (&(srcg->thisMesh), &thisMesh);
} else if(type == EXTRUDE && haveSrc) {
} else if(type == Type::EXTRUDE && haveSrc) {
Group *src = SK.GetGroup(opA);
Vector translate = Vector::From(h.param(0), h.param(1), h.param(2));
Vector tbot, ttop;
if(subtype == ONE_SIDED) {
if(subtype == Subtype::ONE_SIDED) {
tbot = Vector::From(0, 0, 0); ttop = translate.ScaledBy(2);
} else {
tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1);
@ -254,7 +254,7 @@ void Group::GenerateShellAndMesh() {
Entity *e;
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
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(),
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);
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)) {
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
// transformation applied. We also must remap the face entities.
Vector offset = {
@ -305,7 +305,7 @@ void Group::GenerateShellAndMesh() {
thisShell.RemapFaces(this, 0);
}
if(srcg->meshCombine != COMBINE_AS_ASSEMBLE) {
if(srcg->meshCombine != CombineAs::ASSEMBLE) {
thisShell.MergeCoincidentSurfaces();
}
@ -320,7 +320,7 @@ void Group::GenerateShellAndMesh() {
GenerateForBoolean<SShell>(prevs, &thisShell, &runningShell,
srcg->meshCombine);
if(srcg->meshCombine != COMBINE_AS_ASSEMBLE) {
if(srcg->meshCombine != CombineAs::ASSEMBLE) {
runningShell.MergeCoincidentSurfaces();
}
@ -409,10 +409,10 @@ void Group::GenerateDisplayItems() {
if(runningMesh.l.n > 0) {
// Triangle mesh only; no shell or emphasized edges.
runningMesh.MakeCertainEdgesAndOutlinesInto(
&displayEdges, &displayOutlines, SKdNode::EMPHASIZED_EDGES);
&displayEdges, &displayOutlines, EdgeKind::EMPHASIZED);
} else {
displayMesh.MakeCertainEdgesAndOutlinesInto(
&displayEdges, &displayOutlines, SKdNode::SHARP_EDGES);
&displayEdges, &displayOutlines, EdgeKind::SHARP);
}
}
}
@ -432,7 +432,7 @@ Group *Group::PreviousGroup() {
}
Group *Group::RunningMeshGroup() {
if(type == TRANSLATE || type == ROTATE) {
if(type == Type::TRANSLATE || type == Type::ROTATE) {
return SK.GetGroup(opA)->RunningMeshGroup();
} else {
return PreviousGroup();
@ -441,19 +441,19 @@ Group *Group::RunningMeshGroup() {
bool Group::IsMeshGroup() {
switch(type) {
case Group::EXTRUDE:
case Group::LATHE:
case Group::ROTATE:
case Group::TRANSLATE:
case Group::Type::EXTRUDE:
case Group::Type::LATHE:
case Group::Type::ROTATE:
case Group::Type::TRANSLATE:
return true;
}
return false;
}
void Group::DrawDisplayItems(int t) {
void Group::DrawDisplayItems(Group::Type t) {
RgbaColor specColor;
bool useSpecColor;
if(t == DRAWING_3D || t == DRAWING_WORKPLANE) {
if(t == Type::DRAWING_3D || t == Type::DRAWING_WORKPLANE) {
// force the color to something dim
specColor = Style::Color(Style::DIM_SOLID);
useSpecColor = true;
@ -530,10 +530,10 @@ void Group::Draw() {
// And finally show the polygons too, and any errors if it's not possible
// 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
// it's just a nuisance.
if(type == DRAWING_WORKPLANE) {
if(type == Type::DRAWING_WORKPLANE) {
glDisable(GL_DEPTH_TEST);
ssglColorRGBa(Style::Color(Style::DRAW_ERROR), 0.2);
ssglLineWidth (Style::Width(Style::DRAW_ERROR));
@ -548,18 +548,18 @@ void Group::Draw() {
NULL, NULL);
glEnable(GL_DEPTH_TEST);
}
} else if(polyError.how == POLY_NOT_COPLANAR ||
polyError.how == POLY_SELF_INTERSECTING ||
polyError.how == POLY_ZERO_LEN_EDGE)
} else if(polyError.how == PolyError::NOT_COPLANAR ||
polyError.how == PolyError::SELF_INTERSECTING ||
polyError.how == PolyError::ZERO_LEN_EDGE)
{
// These errors occur at points, not lines
if(type == DRAWING_WORKPLANE) {
if(type == Type::DRAWING_WORKPLANE) {
glDisable(GL_DEPTH_TEST);
ssglColorRGB(Style::Color(Style::DRAW_ERROR));
const char *msg;
if(polyError.how == POLY_NOT_COPLANAR) {
if(polyError.how == PolyError::NOT_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!";
} else {
msg = "zero-length edge!";
@ -599,7 +599,7 @@ void Group::DrawFilledPaths() {
FillLoopSetAsPolygon(sbls);
} else {
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
// for closed contours, and we do indeed have a closed and

View File

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

View File

@ -103,16 +103,16 @@ void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
EntityBase e = {};
switch(se->type) {
case SLVS_E_POINT_IN_3D: e.type = Entity::POINT_IN_3D; break;
case SLVS_E_POINT_IN_2D: e.type = Entity::POINT_IN_2D; break;
case SLVS_E_NORMAL_IN_3D: e.type = Entity::NORMAL_IN_3D; break;
case SLVS_E_NORMAL_IN_2D: e.type = Entity::NORMAL_IN_2D; break;
case SLVS_E_DISTANCE: e.type = Entity::DISTANCE; break;
case SLVS_E_WORKPLANE: e.type = Entity::WORKPLANE; break;
case SLVS_E_LINE_SEGMENT: e.type = Entity::LINE_SEGMENT; break;
case SLVS_E_CUBIC: e.type = Entity::CUBIC; break;
case SLVS_E_CIRCLE: e.type = Entity::CIRCLE; break;
case SLVS_E_ARC_OF_CIRCLE: e.type = Entity::ARC_OF_CIRCLE; break;
case SLVS_E_POINT_IN_3D: e.type = Entity::Type::POINT_IN_3D; break;
case SLVS_E_POINT_IN_2D: e.type = Entity::Type::POINT_IN_2D; break;
case SLVS_E_NORMAL_IN_3D: e.type = Entity::Type::NORMAL_IN_3D; break;
case SLVS_E_NORMAL_IN_2D: e.type = Entity::Type::NORMAL_IN_2D; break;
case SLVS_E_DISTANCE: e.type = Entity::Type::DISTANCE; break;
case SLVS_E_WORKPLANE: e.type = Entity::Type::WORKPLANE; break;
case SLVS_E_LINE_SEGMENT: e.type = Entity::Type::LINE_SEGMENT; break;
case SLVS_E_CUBIC: e.type = Entity::Type::CUBIC; break;
case SLVS_E_CIRCLE: e.type = Entity::Type::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;
}
@ -137,42 +137,42 @@ default: dbp("bad entity type %d", se->type); return;
Slvs_Constraint *sc = &(ssys->constraint[i]);
ConstraintBase c = {};
int t;
Constraint::Type t;
switch(sc->type) {
case SLVS_C_POINTS_COINCIDENT: t = Constraint::POINTS_COINCIDENT; break;
case SLVS_C_PT_PT_DISTANCE: t = Constraint::PT_PT_DISTANCE; break;
case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::PT_PLANE_DISTANCE; break;
case SLVS_C_PT_LINE_DISTANCE: t = Constraint::PT_LINE_DISTANCE; break;
case SLVS_C_PT_FACE_DISTANCE: t = Constraint::PT_FACE_DISTANCE; break;
case SLVS_C_PT_IN_PLANE: t = Constraint::PT_IN_PLANE; break;
case SLVS_C_PT_ON_LINE: t = Constraint::PT_ON_LINE; break;
case SLVS_C_PT_ON_FACE: t = Constraint::PT_ON_FACE; break;
case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::EQUAL_LENGTH_LINES; break;
case SLVS_C_LENGTH_RATIO: t = Constraint::LENGTH_RATIO; break;
case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::EQ_LEN_PT_LINE_D; break;
case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::EQ_PT_LN_DISTANCES; break;
case SLVS_C_EQUAL_ANGLE: t = Constraint::EQUAL_ANGLE; break;
case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::EQUAL_LINE_ARC_LEN; break;
case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::LENGTH_DIFFERENCE; break;
case SLVS_C_SYMMETRIC: t = Constraint::SYMMETRIC; break;
case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::SYMMETRIC_HORIZ; break;
case SLVS_C_SYMMETRIC_VERT: t = Constraint::SYMMETRIC_VERT; break;
case SLVS_C_SYMMETRIC_LINE: t = Constraint::SYMMETRIC_LINE; break;
case SLVS_C_AT_MIDPOINT: t = Constraint::AT_MIDPOINT; break;
case SLVS_C_HORIZONTAL: t = Constraint::HORIZONTAL; break;
case SLVS_C_VERTICAL: t = Constraint::VERTICAL; break;
case SLVS_C_DIAMETER: t = Constraint::DIAMETER; break;
case SLVS_C_PT_ON_CIRCLE: t = Constraint::PT_ON_CIRCLE; break;
case SLVS_C_SAME_ORIENTATION: t = Constraint::SAME_ORIENTATION; break;
case SLVS_C_ANGLE: t = Constraint::ANGLE; break;
case SLVS_C_PARALLEL: t = Constraint::PARALLEL; break;
case SLVS_C_PERPENDICULAR: t = Constraint::PERPENDICULAR; break;
case SLVS_C_ARC_LINE_TANGENT: t = Constraint::ARC_LINE_TANGENT; break;
case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::CUBIC_LINE_TANGENT; break;
case SLVS_C_EQUAL_RADIUS: t = Constraint::EQUAL_RADIUS; break;
case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::PROJ_PT_DISTANCE; break;
case SLVS_C_WHERE_DRAGGED: t = Constraint::WHERE_DRAGGED; break;
case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::CURVE_CURVE_TANGENT; break;
case SLVS_C_POINTS_COINCIDENT: t = Constraint::Type::POINTS_COINCIDENT; break;
case SLVS_C_PT_PT_DISTANCE: t = Constraint::Type::PT_PT_DISTANCE; break;
case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::Type::PT_PLANE_DISTANCE; break;
case SLVS_C_PT_LINE_DISTANCE: t = Constraint::Type::PT_LINE_DISTANCE; break;
case SLVS_C_PT_FACE_DISTANCE: t = Constraint::Type::PT_FACE_DISTANCE; break;
case SLVS_C_PT_IN_PLANE: t = Constraint::Type::PT_IN_PLANE; break;
case SLVS_C_PT_ON_LINE: t = Constraint::Type::PT_ON_LINE; break;
case SLVS_C_PT_ON_FACE: t = Constraint::Type::PT_ON_FACE; break;
case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::Type::EQUAL_LENGTH_LINES; break;
case SLVS_C_LENGTH_RATIO: t = Constraint::Type::LENGTH_RATIO; 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::Type::EQ_PT_LN_DISTANCES; break;
case SLVS_C_EQUAL_ANGLE: t = Constraint::Type::EQUAL_ANGLE; break;
case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::Type::EQUAL_LINE_ARC_LEN; break;
case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::Type::LENGTH_DIFFERENCE; break;
case SLVS_C_SYMMETRIC: t = Constraint::Type::SYMMETRIC; break;
case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::Type::SYMMETRIC_HORIZ; break;
case SLVS_C_SYMMETRIC_VERT: t = Constraint::Type::SYMMETRIC_VERT; break;
case SLVS_C_SYMMETRIC_LINE: t = Constraint::Type::SYMMETRIC_LINE; break;
case SLVS_C_AT_MIDPOINT: t = Constraint::Type::AT_MIDPOINT; break;
case SLVS_C_HORIZONTAL: t = Constraint::Type::HORIZONTAL; break;
case SLVS_C_VERTICAL: t = Constraint::Type::VERTICAL; break;
case SLVS_C_DIAMETER: t = Constraint::Type::DIAMETER; break;
case SLVS_C_PT_ON_CIRCLE: t = Constraint::Type::PT_ON_CIRCLE; break;
case SLVS_C_SAME_ORIENTATION: t = Constraint::Type::SAME_ORIENTATION; break;
case SLVS_C_ANGLE: t = Constraint::Type::ANGLE; break;
case SLVS_C_PARALLEL: t = Constraint::Type::PARALLEL; break;
case SLVS_C_PERPENDICULAR: t = Constraint::Type::PERPENDICULAR; break;
case SLVS_C_ARC_LINE_TANGENT: t = Constraint::Type::ARC_LINE_TANGENT; break;
case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::Type::CUBIC_LINE_TANGENT; break;
case SLVS_C_EQUAL_RADIUS: t = Constraint::Type::EQUAL_RADIUS; break;
case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::Type::PROJ_PT_DISTANCE; break;
case SLVS_C_WHERE_DRAGGED: t = Constraint::Type::WHERE_DRAGGED; break;
case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::Type::CURVE_CURVE_TANGENT; break;
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!
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) {
case System::SOLVED_OKAY:
case SolveResult::OKAY:
ssys->result = SLVS_RESULT_OKAY;
break;
case System::DIDNT_CONVERGE:
case SolveResult::DIDNT_CONVERGE:
ssys->result = SLVS_RESULT_DIDNT_CONVERGE;
break;
case System::REDUNDANT_DIDNT_CONVERGE:
case System::REDUNDANT_OKAY:
case SolveResult::REDUNDANT_DIDNT_CONVERGE:
case SolveResult::REDUNDANT_OKAY:
ssys->result = SLVS_RESULT_INCONSISTENT;
break;
case System::TOO_MANY_UNKNOWNS:
case SolveResult::TOO_MANY_UNKNOWNS:
ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS;
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.
SKdNode *root = SKdNode::From(&m);
root->SnapToMesh(&m);
root->MakeCertainEdgesInto(sel, SKdNode::NAKED_OR_SELF_INTER_EDGES,
root->MakeCertainEdgesInto(sel, EdgeKind::NAKED_OR_SELF_INTER,
false, NULL, NULL);
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);
root->MakeCertainEdgesInto(sel, type, false, NULL, NULL);
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
// 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
{
if(inter) *inter = false;
@ -945,7 +945,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
FindEdgeOn(a, b, cnt, coplanarIsInter, &info);
switch(how) {
case NAKED_OR_SELF_INTER_EDGES:
case EdgeKind::NAKED_OR_SELF_INTER:
if(info.count != 1) {
sel->AddEdge(a, b, auxA);
if(leaky) *leaky = true;
@ -956,14 +956,14 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
}
break;
case SELF_INTER_EDGES:
case EdgeKind::SELF_INTER:
if(info.intersectsMesh) {
sel->AddEdge(a, b, auxA);
if(inter) *inter = true;
}
break;
case TURNING_EDGES:
case EdgeKind::TURNING:
if((tr->Normal().z < LENGTH_EPS) &&
(info.count == 1) &&
info.frontFacing)
@ -977,7 +977,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
}
break;
case EMPHASIZED_EDGES:
case EdgeKind::EMPHASIZED:
if(info.count == 1 && tr->meta.face != info.tr->meta.face) {
if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr))
break;
@ -989,7 +989,7 @@ void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, int how, bool coplanarIsInter
}
break;
case SHARP_EDGES:
case EdgeKind::SHARP:
if(info.count == 1) {
Vector na0 = (j == 0) ? tr->an :
((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) {
c->tag = 1;
(SS.deleted.constraints)++;
if(c->type != Constraint::POINTS_COINCIDENT &&
c->type != Constraint::HORIZONTAL &&
c->type != Constraint::VERTICAL)
if(c->type != Constraint::Type::POINTS_COINCIDENT &&
c->type != Constraint::Type::HORIZONTAL &&
c->type != Constraint::Type::VERTICAL)
{
(SS.deleted.nonTrivialConstraints)++;
}
@ -56,8 +56,8 @@ void GraphicsWindow::FixConstraintsForRequestBeingDeleted(hRequest hr) {
if(!(e->h.isFromRequest())) continue;
if(e->h.request().v != hr.v) continue;
if(e->type != Entity::POINT_IN_2D &&
e->type != Entity::POINT_IN_3D)
if(e->type != Entity::Type::POINT_IN_2D &&
e->type != Entity::Type::POINT_IN_3D)
{
continue;
}
@ -73,7 +73,7 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
Constraint *c;
SK.constraint.ClearTags();
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->ptA.v == hpt.v) {
@ -111,14 +111,14 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
void GraphicsWindow::ParametricCurve::MakeFromEntity(hEntity he, bool reverse) {
*this = {};
Entity *e = SK.GetEntity(he);
if(e->type == Entity::LINE_SEGMENT) {
if(e->type == Entity::Type::LINE_SEGMENT) {
isLine = true;
p0 = e->EndpointStart(),
p1 = e->EndpointFinish();
if(reverse) {
swap(p0, p1);
}
} else if(e->type == Entity::ARC_OF_CIRCLE) {
} else if(e->type == Entity::Type::ARC_OF_CIRCLE) {
isLine = false;
p0 = SK.GetEntity(e->point[0])->PointGetNum();
Vector pe = SK.GetEntity(e->point[1])->PointGetNum();
@ -167,21 +167,21 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
hRequest hr;
Entity *e;
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));
SK.GetEntity(e->point[0])->PointForceTo(PointAt(t));
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
ConstrainPointIfCoincident(e->point[0]);
ConstrainPointIfCoincident(e->point[1]);
if(extraConstraints) {
Constraint::Constrain(Constraint::PT_ON_LINE,
Constraint::Constrain(Constraint::Type::PT_ON_LINE,
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,
arc, e->h, arcFinish, false);
} 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));
SK.GetEntity(e->point[0])->PointForceTo(p0);
if(dtheta > 0) {
@ -196,7 +196,7 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
ConstrainPointIfCoincident(e->point[2]);
// The tangency constraint alone is enough to fully constrain it,
// 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,
arc, e->h, arcFinish, (dtheta < 0));
}
@ -257,8 +257,8 @@ void GraphicsWindow::MakeTangentArc() {
if(r->group.v != activeGroup.v) continue;
if(r->workplane.v != ActiveWorkplane().v) continue;
if(r->construction) continue;
if(r->type != Request::LINE_SEGMENT &&
r->type != Request::ARC_OF_CIRCLE)
if(r->type != Request::Type::LINE_SEGMENT &&
r->type != Request::Type::ARC_OF_CIRCLE)
{
continue;
}
@ -389,7 +389,7 @@ void GraphicsWindow::MakeTangentArc() {
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));
hEntity hearc = earc->h;
@ -432,8 +432,8 @@ hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
p1 = SK.GetEntity(hep1)->PointGetNum();
// Add the two line segments this one gets split into.
hRequest r0i = AddRequest(Request::LINE_SEGMENT, false),
ri1 = AddRequest(Request::LINE_SEGMENT, false);
hRequest r0i = AddRequest(Request::Type::LINE_SEGMENT, false),
ri1 = AddRequest(Request::Type::LINE_SEGMENT, false);
// Don't get entities till after adding, realloc issues
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) {
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.
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
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));
@ -477,8 +477,8 @@ hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
finish = SK.GetEntity(hf)->PointGetNum();
circle = NULL; // shortly invalid!
hRequest hr0 = AddRequest(Request::ARC_OF_CIRCLE, false),
hr1 = AddRequest(Request::ARC_OF_CIRCLE, false);
hRequest hr0 = AddRequest(Request::Type::ARC_OF_CIRCLE, false),
hr1 = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
Entity *arc0 = SK.GetEntity(hr0.entity(0)),
*arc1 = SK.GetEntity(hr1.entity(0));
@ -525,8 +525,8 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
b01.SplitAt(t, &b0i, &bi1);
// Add the two cubic segments this one gets split into.
hRequest r0i = AddRequest(Request::CUBIC, false),
ri1 = AddRequest(Request::CUBIC, false);
hRequest r0i = AddRequest(Request::Type::CUBIC, false),
ri1 = AddRequest(Request::Type::CUBIC, false);
// Don't get entities till after adding, realloc issues
Entity *e0i = SK.GetEntity(r0i.entity(0)),
@ -544,7 +544,7 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
hep1n = ei1->point[3];
hepin = e0i->point[3];
} else {
hRequest r = AddRequest(Request::CUBIC, false);
hRequest r = AddRequest(Request::Type::CUBIC, false);
Entity *e = SK.GetEntity(r.entity(0));
for(j = 0; j <= 3; j++) {
@ -565,14 +565,14 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
Entity *e = SK.GetEntity(he);
int entityType = e->type;
Entity::Type entityType = e->type;
hEntity ret;
if(e->IsCircle()) {
ret = SplitCircle(he, pinter);
} else if(e->type == Entity::LINE_SEGMENT) {
} else if(e->type == Entity::Type::LINE_SEGMENT) {
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);
} else {
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.
int reqType = EntReqTable::GetRequestForEntity(entityType);
Request::Type reqType = EntReqTable::GetRequestForEntity(entityType);
SK.request.ClearTags();
for(int i = 0; i < SK.request.n; i++) {
Request *r = &(SK.request.elem[i]);

View File

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

View File

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

View File

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

View File

@ -185,20 +185,20 @@ void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error)
DestroyWindow(MessageWnd);
}
void SolveSpace::AddContextMenuItem(const char *label, int id)
void SolveSpace::AddContextMenuItem(const char *label, ContextCommand cmd)
{
if(!ContextMenu) ContextMenu = CreatePopupMenu();
if(id == CONTEXT_SUBMENU) {
if(cmd == ContextCommand::SUBMENU) {
AppendMenuW(ContextMenu, MF_STRING | MF_POPUP,
(UINT_PTR)ContextSubmenu, Widen(label).c_str());
ContextSubmenu = NULL;
} else {
HMENU m = ContextSubmenu ? ContextSubmenu : ContextMenu;
if(id == CONTEXT_SEPARATOR) {
if(cmd == ContextCommand::SEPARATOR) {
AppendMenuW(m, MF_SEPARATOR, 0, L"");
} 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();
}
int SolveSpace::ShowContextMenu()
ContextCommand SolveSpace::ShowContextMenu()
{
POINT p;
GetCursorPos(&p);
@ -218,7 +218,7 @@ int SolveSpace::ShowContextMenu()
DestroyMenu(ContextMenu);
ContextMenu = NULL;
return r;
return (ContextCommand)r;
}
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_DESTROY:
SolveSpaceUI::MenuFile(GraphicsWindow::MNU_EXIT);
SolveSpaceUI::MenuFile(Command::EXIT);
break;
case WM_PAINT: {
@ -699,7 +699,7 @@ static bool ProcessKeyDown(WPARAM wParam)
for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
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;
}
}
@ -937,19 +937,21 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_COMMAND: {
if(HIWORD(wParam) == 0) {
int id = LOWORD(wParam);
if((id >= RECENT_OPEN && id < (RECENT_OPEN + MAX_RECENT))) {
Command id = (Command)LOWORD(wParam);
if(((uint32_t)id >= (uint32_t)Command::RECENT_OPEN &&
(uint32_t)id < ((uint32_t)Command::RECENT_OPEN + MAX_RECENT))) {
SolveSpaceUI::MenuFile(id);
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);
break;
}
int i;
for(i = 0; SS.GW.menu[i].level >= 0; i++) {
if(id == SS.GW.menu[i].id) {
(SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id);
(SS.GW.menu[i].fn)((Command)id);
break;
}
}
@ -960,7 +962,7 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_CLOSE:
case WM_DESTROY:
SolveSpaceUI::MenuFile(GraphicsWindow::MNU_EXIT);
SolveSpaceUI::MenuFile(Command::EXIT);
return 1;
default:
@ -1142,7 +1144,7 @@ std::vector<std::string> SolveSpace::GetFontFiles() {
return fonts;
}
static void MenuById(int id, bool yes, bool check)
static void MenuByCmd(Command id, bool yes, bool check)
{
int i;
int subMenu = -1;
@ -1155,10 +1157,10 @@ static void MenuById(int id, bool yes, bool check)
"Submenu out of range");
if(check) {
CheckMenuItem(SubMenus[subMenu], id,
CheckMenuItem(SubMenus[subMenu], (uint32_t)id,
yes ? MF_CHECKED : MF_UNCHECKED);
} else {
EnableMenuItem(SubMenus[subMenu], id,
EnableMenuItem(SubMenus[subMenu], (uint32_t)id,
yes ? MF_ENABLED : MF_GRAYED);
}
return;
@ -1166,27 +1168,27 @@ static void MenuById(int id, bool yes, bool check)
}
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
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))
;
int i, c = 0;
for(i = 0; i < MAX_RECENT; i++) {
int c = 0;
for(size_t i = 0; i < MAX_RECENT; i++) {
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++;
}
}
@ -1194,8 +1196,8 @@ static void DoRecent(HMENU m, int base)
}
void SolveSpace::RefreshRecentMenus()
{
DoRecent(RecentOpenMenu, RECENT_OPEN);
DoRecent(RecentImportMenu, RECENT_LINK);
DoRecent(RecentOpenMenu, Command::RECENT_OPEN);
DoRecent(RecentImportMenu, Command::RECENT_LINK);
}
HMENU CreateGraphicsWindowMenus()
@ -1221,18 +1223,18 @@ HMENU CreateGraphicsWindowMenus()
SubMenus[subMenu] = m;
subMenu++;
} 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();
AppendMenuW(m, MF_STRING | MF_POPUP,
(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();
AppendMenuW(m, MF_STRING | MF_POPUP,
(UINT_PTR)RecentImportMenu, Widen(label).c_str());
} 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 {
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");
}

View File

@ -15,6 +15,26 @@ class SMesh;
class SBsp3;
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 {
public:
int tag;
@ -75,12 +95,7 @@ class SPoint {
public:
int tag;
enum {
UNKNOWN = 0,
NOT_EAR = 1,
EAR = 2
};
int ear;
EarType ear;
Vector p;
Vector auxv;
@ -177,8 +192,7 @@ public:
SBsp2 *more;
enum { POS = 100, NEG = 101, COPLANAR = 200 };
void InsertTriangleHow(int how, STriangle *tr, SMesh *m, SBsp3 *bsp3);
void InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3);
void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3);
Vector IntersectionWith(Vector a, Vector b) const;
void InsertEdge(SEdge *nedge, Vector nnp, Vector out);
@ -207,12 +221,11 @@ public:
Vector IntersectionWith(Vector a, Vector b) const;
enum { POS = 100, NEG = 101, COPLANAR = 200 };
void InsertHow(int how, STriangle *str, SMesh *instead);
void InsertHow(BspClass how, STriangle *str, SMesh *instead);
void Insert(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);
SBsp3 *InsertConvex(STriMeta meta, Vector *vertex, int n, SMesh *instead);
@ -252,7 +265,7 @@ public:
void MakeFromAssemblyOf(SMesh *a, SMesh *b);
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;
void RemapFaces(Group *g, int remap);
@ -317,14 +330,7 @@ public:
void ClearTags() const;
void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info) const;
enum {
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,
void MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter,
bool *inter, bool *leaky, int auxA = 0) const;
void MakeOutlinesInto(SOutlineList *sel) const;

View File

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

View File

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

View File

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

View File

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

View File

@ -9,11 +9,11 @@
static int I;
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) {
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,
// and it doesn't hurt to split unnecessarily.
Point2d dummy = { 0, 0 };
int c = (pi->srf->bsp) ? pi->srf->bsp->ClassifyPoint(puv, dummy, pi->srf) : SBspUv::OUTSIDE;
if(c == SBspUv::OUTSIDE) {
SBspUv::Class c = (pi->srf->bsp) ? pi->srf->bsp->ClassifyPoint(puv, dummy, pi->srf) : SBspUv::Class::OUTSIDE;
if(c == SBspUv::Class::OUTSIDE) {
double d = VERY_POSITIVE;
if(pi->srf->bsp) d = pi->srf->bsp->MinimumDistanceToEdge(puv, pi->srf);
if(d > SS.ChordTolMm()) {
@ -135,7 +135,7 @@ void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) {
SCurve scn = sc->MakeCopySplitAgainst(agnst, NULL,
surface.FindById(sc->surfA),
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);
// 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),
inSame = (shell == SShell::COINC_SAME),
inOpp = (shell == SShell::COINC_OPP),
inOrig = (orig == SShell::INSIDE);
bool inShell = (shell == SShell::Class::INSIDE),
inSame = (shell == SShell::Class::COINC_SAME),
inOpp = (shell == SShell::Class::COINC_OPP),
inOrig = (orig == SShell::Class::INSIDE);
bool inFace = inSame || inOpp;
@ -207,14 +207,14 @@ static bool KeepRegion(int type, bool opA, int shell, int orig)
// if inFace is true.
if(!inOrig) return false;
switch(type) {
case SShell::AS_UNION:
case SSurface::CombineAs::UNION:
if(opA) {
return (!inShell && !inFace);
} else {
return (!inShell && !inFace) || inSame;
}
case SShell::AS_DIFFERENCE:
case SSurface::CombineAs::DIFFERENCE:
if(opA) {
return (!inShell && !inFace);
} else {
@ -224,9 +224,9 @@ static bool KeepRegion(int type, bool opA, int shell, int orig)
default: ssassert(false, "Unexpected shell type");
}
}
static bool KeepEdge(int type, bool opA,
int indir_shell, int outdir_shell,
int indir_orig, int outdir_orig)
static bool KeepEdge(SSurface::CombineAs type, bool opA,
SShell::Class indir_shell, SShell::Class outdir_shell,
SShell::Class indir_orig, SShell::Class outdir_orig)
{
bool keepIn = KeepRegion(type, opA, indir_shell, indir_orig),
keepOut = KeepRegion(type, opA, outdir_shell, outdir_orig);
@ -237,33 +237,33 @@ static bool KeepEdge(int type, bool opA,
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) {
case SBspUv::INSIDE:
*indir = SShell::INSIDE;
*outdir = SShell::INSIDE;
case SBspUv::Class::INSIDE:
*indir = SShell::Class::INSIDE;
*outdir = SShell::Class::INSIDE;
break;
case SBspUv::OUTSIDE:
*indir = SShell::OUTSIDE;
*outdir = SShell::OUTSIDE;
case SBspUv::Class::OUTSIDE:
*indir = SShell::Class::OUTSIDE;
*outdir = SShell::Class::OUTSIDE;
break;
case SBspUv::EDGE_PARALLEL:
*indir = SShell::INSIDE;
*outdir = SShell::OUTSIDE;
case SBspUv::Class::EDGE_PARALLEL:
*indir = SShell::Class::INSIDE;
*outdir = SShell::Class::OUTSIDE;
break;
case SBspUv::EDGE_ANTIPARALLEL:
*indir = SShell::OUTSIDE;
*outdir = SShell::INSIDE;
case SBspUv::Class::EDGE_ANTIPARALLEL:
*indir = SShell::Class::OUTSIDE;
*outdir = SShell::Class::INSIDE;
break;
default:
dbp("TagByClassifiedEdge: fail!");
*indir = SShell::OUTSIDE;
*outdir = SShell::OUTSIDE;
*indir = SShell::Class::OUTSIDE;
*outdir = SShell::Class::OUTSIDE;
break;
}
}
@ -400,7 +400,7 @@ void SSurface::EdgeNormalsWithinSurface(Point2d auv, Point2d buv,
SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
SShell *sha, SShell *shb,
SShell *into,
int type)
SSurface::CombineAs type)
{
bool opA = (parent == sha);
SShell *agnst = opA ? shb : sha;
@ -419,7 +419,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
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
ret.Reverse();
}
@ -428,7 +428,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
// be changed if we just flipped the surface normal, and we are using
// the split curves (not the original curves).
SEdgeList orig = {};
ret.MakeEdgesInto(into, &orig, AS_UV);
ret.MakeEdgesInto(into, &orig, MakeAs::UV);
ret.trim.Clear();
// which means that we can't necessarily use the old BSP...
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)) {
SCurve *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(sc->surfA.v != h.v || sc->surfB.v != ss->h.v) continue;
} else {
@ -456,8 +456,8 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ss->ClosestPointTo(a, &(auv.x), &(auv.y));
ss->ClosestPointTo(b, &(buv.x), &(buv.y));
int c = (ss->bsp) ? ss->bsp->ClassifyEdge(auv, buv, ss) : SBspUv::OUTSIDE;
if(c != SBspUv::OUTSIDE) {
SBspUv::Class c = (ss->bsp) ? ss->bsp->ClassifyEdge(auv, buv, ss) : SBspUv::Class::OUTSIDE;
if(c != SBspUv::Class::OUTSIDE) {
Vector ta = Vector::From(0, 0, 0);
Vector tb = Vector::From(0, 0, 0);
ret.ClosestPointTo(a, &(ta.x), &(ta.y));
@ -471,7 +471,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
// point opposite to the surface normal.
bool bkwds = true;
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) {
inter.AddEdge(tb, ta, sc->h.v, 1);
} else {
@ -525,10 +525,10 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn,
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;
outdir_orig = SShell::OUTSIDE;
indir_orig = SShell::Class::INSIDE;
outdir_orig = SShell::Class::OUTSIDE;
agnst->ClassifyEdge(&indir_shell, &outdir_shell,
ret.PointAt(auv), ret.PointAt(buv), pt,
@ -558,9 +558,9 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn,
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);
agnst->ClassifyEdge(&indir_shell, &outdir_shell,
@ -602,7 +602,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
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;
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
SSurface ssn;
@ -667,7 +667,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
ab = (i == 0) ? a : b;
for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) {
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
// we've assigned IDs to the surfaces. So we'll get that later.
c->newH = curve.AddAndAssignId(&cn);
@ -695,7 +695,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *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;
a->MakeClassifyingBsps(NULL);
@ -759,12 +759,12 @@ void SShell::MakeClassifyingBsps(SShell *useCurvesFrom) {
void SSurface::MakeClassifyingBsp(SShell *shell, SShell *useCurvesFrom) {
SEdgeList el = {};
MakeEdgesInto(shell, &el, AS_UV, useCurvesFrom);
MakeEdgesInto(shell, &el, MakeAs::UV, useCurvesFrom);
bsp = SBspUv::From(&el, this);
el.Clear();
edges = {};
MakeEdgesInto(shell, &edges, AS_XYZ, useCurvesFrom);
MakeEdgesInto(shell, &edges, MakeAs::XYZ, useCurvesFrom);
}
SBspUv *SBspUv::Alloc() {
@ -898,7 +898,7 @@ void SBspUv::InsertEdge(Point2d ea, Point2d eb, SSurface *srf) {
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);
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(eb, f->a, ba, false, srf) < LENGTH_EPS){
if(ba.Dot(eb.Minus(p)) > 0) {
return EDGE_PARALLEL;
return Class::EDGE_PARALLEL;
} else {
return EDGE_ANTIPARALLEL;
return Class::EDGE_ANTIPARALLEL;
}
} else {
return EDGE_OTHER;
return Class::EDGE_OTHER;
}
}
f = f->more;
}
// Pick arbitrarily which side to send it down, doesn't matter
int c1 = neg ? neg->ClassifyPoint(p, eb, srf) : OUTSIDE;
int c2 = pos ? pos->ClassifyPoint(p, eb, srf) : INSIDE;
Class c1 = neg ? neg->ClassifyPoint(p, eb, srf) : Class::OUTSIDE;
Class c2 = pos ? pos->ClassifyPoint(p, eb, srf) : Class::INSIDE;
if(c1 != c2) {
dbp("MISMATCH: %d %d %08x %08x", c1, c2, neg, pos);
}
return c1;
} else if(dp > 0) {
return pos ? pos->ClassifyPoint(p, eb, srf) : INSIDE;
return pos ? pos->ClassifyPoint(p, eb, srf) : Class::INSIDE;
} 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 {
int ret = ClassifyPoint((ea.Plus(eb)).ScaledBy(0.5), eb, srf);
if(ret == EDGE_OTHER) {
SBspUv::Class SBspUv::ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const {
SBspUv::Class ret = ClassifyPoint((ea.Plus(eb)).ScaledBy(0.5), eb, srf);
if(ret == Class::EDGE_OTHER) {
// Perhaps the edge is tangent at its midpoint (and we screwed up
// somewhere earlier and failed to split it); try a different
// point on the edge.

View File

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

View File

@ -23,7 +23,7 @@ void SShell::MergeCoincidentSurfaces() {
if(si->degm != 1 || si->degn != 1) continue;
SEdgeList sel = {};
si->MakeEdgesInto(this, &sel, SSurface::AS_XYZ);
si->MakeEdgesInto(this, &sel, SSurface::MakeAs::XYZ);
bool mergedThisTime, merged = false;
do {
@ -42,7 +42,7 @@ void SShell::MergeCoincidentSurfaces() {
// the bounding box tests less effective, and possibly things
// less robust.
SEdgeList tel = {};
sj->MakeEdgesInto(this, &tel, SSurface::AS_XYZ);
sj->MakeEdgesInto(this, &tel, SSurface::MakeAs::XYZ);
if(!sel.ContainsEdgeFrom(&tel)) {
tel.Clear();
continue;
@ -52,7 +52,7 @@ void SShell::MergeCoincidentSurfaces() {
sj->tag = 1;
merged = true;
mergedThisTime = true;
sj->MakeEdgesInto(this, &sel, SSurface::AS_XYZ);
sj->MakeEdgesInto(this, &sel, SSurface::MakeAs::XYZ);
sj->trim.Clear();
// 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
Point2d dummy = { 0, 0 };
int c = (bsp) ? bsp->ClassifyPoint(puv, dummy, this) : SBspUv::OUTSIDE;
if(trimmed && c == SBspUv::OUTSIDE) {
SBspUv::Class c = (bsp) ? bsp->ClassifyPoint(puv, dummy, this) : SBspUv::Class::OUTSIDE;
if(trimmed && c == SBspUv::Class::OUTSIDE) {
continue;
}
@ -372,7 +372,7 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
si.surfNormal = NormalAt(puv.x, puv.y);
si.pinter = puv;
si.srf = this;
si.onEdge = (c != SBspUv::INSIDE);
si.onEdge = (c != SBspUv::Class::INSIDE);
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
{
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
// to see if it's with same or opposite normals.
if(inter_surf_n.Dot(edge_surf_n) > 0) {
return COINC_SAME;
return Class::COINC_SAME;
} else {
return COINC_OPP;
return Class::COINC_OPP;
}
} else if(dot > 0) {
return OUTSIDE;
return Class::OUTSIDE;
} 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,
// 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 p,
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]);
}
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) {
// 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) {
if(edge_n_out.Dot(inter_edge_n[0]) > 0) {
*indir = coinc;
*outdir = OUTSIDE;
*outdir = Class::OUTSIDE;
} else {
*indir = INSIDE;
*indir = Class::INSIDE;
*outdir = coinc;
}
} else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] < -DOTP_TOL) {
if(edge_n_out.Dot(inter_edge_n[0]) > 0) {
*indir = coinc;
*outdir = INSIDE;
*outdir = Class::INSIDE;
} else {
*indir = OUTSIDE;
*indir = Class::OUTSIDE;
*outdir = coinc;
}
} else if(dotp[0] > DOTP_TOL && dotp[1] > DOTP_TOL) {
*indir = INSIDE;
*outdir = OUTSIDE;
*indir = Class::INSIDE;
*outdir = Class::OUTSIDE;
} else if(dotp[0] < -DOTP_TOL && dotp[1] < -DOTP_TOL) {
*indir = OUTSIDE;
*outdir = INSIDE;
*indir = Class::OUTSIDE;
*outdir = Class::INSIDE;
} else {
// Edge is tangent to the shell at shell's edge, so can't be
// a boundary of the surface.
@ -527,8 +527,8 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
Point2d dummy = { 0, 0 };
int c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::OUTSIDE;
if(c == SBspUv::OUTSIDE) continue;
SBspUv::Class c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::Class::OUTSIDE;
if(c == SBspUv::Class::OUTSIDE) continue;
// Edge-on-face (unless edge-on-edge above superceded)
Point2d pin, pout;
@ -556,8 +556,8 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
p.Minus(ray), p.Plus(ray), &l, false, true, false);
// no intersections means it's outside
*indir = OUTSIDE;
*outdir = OUTSIDE;
*indir = Class::OUTSIDE;
*outdir = Class::OUTSIDE;
double dmin = VERY_POSITIVE;
bool onEdge = false;
edge_inters = 0;
@ -583,11 +583,11 @@ bool SShell::ClassifyEdge(int *indir, int *outdir,
// Edge does not lie on surface; either strictly inside
// or strictly outside
if((si->surfNormal).Dot(ray) > 0) {
*indir = INSIDE;
*outdir = INSIDE;
*indir = Class::INSIDE;
*outdir = Class::INSIDE;
} else {
*indir = OUTSIDE;
*outdir = OUTSIDE;
*indir = Class::OUTSIDE;
*outdir = Class::OUTSIDE;
}
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
// to the curve sc.
//-----------------------------------------------------------------------------
void SSurface::MakeTrimEdgesInto(SEdgeList *sel, int flags,
void SSurface::MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags,
SCurve *sc, STrimBy *stb)
{
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) {
Vector tpt, *pt = &(sc->pts.elem[i].p);
if(flags & AS_UV) {
if(flags == MakeAs::UV) {
ClosestPointTo(*pt, &u, &v);
tpt = Vector::From(u, v, 0);
} else {
@ -251,7 +251,7 @@ void SSurface::MakeTrimEdgesInto(SEdgeList *sel, int flags,
// the split curves from useCurvesFrom instead of the curves in our own
// shell.
//-----------------------------------------------------------------------------
void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, int flags,
void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, MakeAs flags,
SShell *useCurvesFrom)
{
STrimBy *stb;
@ -391,7 +391,7 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
sp = fpt;
}
} 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) {
SEdgeList el = {};
MakeEdgesInto(shell, &el, AS_UV);
MakeEdgesInto(shell, &el, MakeAs::UV);
SPolygon poly = {};
if(el.AssemblePolygon(&poly, NULL, true)) {
@ -836,7 +836,7 @@ void SShell::MakeFromTransformationOf(SShell *a,
void SShell::MakeEdgesInto(SEdgeList *sel) {
SSurface *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
#define __SURFACE_H
#ifdef WIN32
#undef DIFFERENCE
#endif
// Utility functions, Bernstein polynomials of order 1-3 and their derivatives.
double Bernstein(int k, int deg, double t);
double BernsteinDerivative(int k, int deg, double t);
@ -28,7 +32,7 @@ public:
SBspUv *more;
enum {
enum class Class : uint32_t {
INSIDE = 100,
OUTSIDE = 200,
EDGE_PARALLEL = 300,
@ -47,8 +51,8 @@ public:
void InsertEdge(Point2d a, Point2d b, SSurface *srf);
static SBspUv *InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf);
int ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const;
int ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const;
Class ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const;
Class ClassifyEdge(Point2d ea, Point2d eb, 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,
// we use newH to record their new handle in C.
hSCurve newH;
enum {
FROM_A = 100,
FROM_B = 200,
FROM_INTERSECTION = 300
enum class Source : uint32_t {
A = 100,
B = 200,
INTERSECTION = 300
};
int source;
Source source;
bool isExact;
SBezier exact;
@ -246,6 +250,13 @@ public:
// A rational polynomial surface in Bezier form.
class SSurface {
public:
enum class CombineAs : uint32_t {
UNION = 10,
DIFFERENCE = 11,
INTERSECT = 12
};
int tag;
hSSurface h;
@ -286,7 +297,7 @@ public:
SShell *shell, SShell *sha, SShell *shb);
void FindChainAvoiding(SEdgeList *src, SEdgeList *dest, SPointList *avoid);
SSurface MakeCopyTrimAgainst(SShell *parent, SShell *a, SShell *b,
SShell *into, int type);
SShell *into, SSurface::CombineAs type);
void TrimFromEdgeList(SEdgeList *el, bool asUv);
void IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
SShell *into);
@ -335,12 +346,12 @@ public:
void TriangulateInto(SShell *shell, SMesh *sm);
// these are intended as bitmasks, even though there's just one now
enum {
AS_UV = 0x01,
AS_XYZ = 0x00
enum class MakeAs : uint32_t {
UV = 0x01,
XYZ = 0x00
};
void MakeTrimEdgesInto(SEdgeList *sel, int flags, SCurve *sc, STrimBy *stb);
void MakeEdgesInto(SShell *shell, SEdgeList *sel, int flags,
void MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags, SCurve *sc, STrimBy *stb);
void MakeEdgesInto(SShell *shell, SEdgeList *sel, MakeAs flags,
SShell *useCurvesFrom=NULL);
Vector ExactSurfaceTangentAt(Vector p, SSurface *srfA, SSurface *srfB,
@ -370,14 +381,9 @@ public:
void MakeFromUnionOf(SShell *a, SShell *b);
void MakeFromDifferenceOf(SShell *a, SShell *b);
enum {
AS_UNION = 10,
AS_DIFFERENCE = 11,
AS_INTERSECT = 12
};
void MakeFromBoolean(SShell *a, SShell *b, int type);
void MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type);
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 MakeClassifyingBsps(SShell *useCurvesFrom);
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,
// outside, or coincident (with parallel or antiparallel normal) with a
// shell.
enum {
enum class Class : uint32_t {
INSIDE = 100,
OUTSIDE = 200,
COINC_SAME = 300,
COINC_OPP = 400
};
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;
bool ClassifyEdge(int *indir, int *outdir,
bool ClassifyEdge(Class *indir, Class *outdir,
Vector ea, Vector eb,
Vector p, Vector edge_n_in,
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()),
"Unexpected zero-length edge");
split.source = SCurve::FROM_INTERSECTION;
split.source = SCurve::Source::INTERSECTION;
into->curve.AddAndAssignId(&split);
}
@ -317,7 +317,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
*srfB = (a == 0) ? b : this;
SEdgeList el = {};
srfA->MakeEdgesInto(shA, &el, AS_XYZ, NULL);
srfA->MakeEdgesInto(shA, &el, MakeAs::XYZ, NULL);
SEdge *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.surfB = b->h;
sc.isExact = false;
sc.source = SCurve::FROM_INTERSECTION;
sc.source = SCurve::Source::INTERSECTION;
Vector start = spl.l.elem[0].p,
startv = spl.l.elem[0].auxv;
@ -502,7 +502,7 @@ void SShell::MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
SSurface *ss;
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
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
// on either side.
l.elem[ap].ear = SPoint::UNKNOWN;
l.elem[cp].ear = SPoint::UNKNOWN;
l.elem[ap].ear = EarType::UNKNOWN;
l.elem[cp].ear = EarType::UNKNOWN;
l.ClearTags();
l.elem[bp].tag = 1;
@ -307,16 +307,16 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
// Now calculate the ear-ness of each vertex
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;
while(l.n > 3) {
// Some points may have changed ear-ness, so recalculate
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) ?
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;
for(i = 0; i < l.n; i++) {
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) {
// This is a plane; any ear is a good ear.
bestEar = ear;

View File

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

View File

@ -90,9 +90,9 @@ void System::SolveBySubstitution() {
Equation *teq = &(eq.elem[i]);
Expr *tex = teq->e;
if(tex->op == Expr::MINUS &&
tex->a->op == Expr::PARAM &&
tex->b->op == Expr::PARAM)
if(tex->op == Expr::Op::MINUS &&
tex->a->op == Expr::Op::PARAM &&
tex->b->op == Expr::Op::PARAM)
{
hParam a = tex->a->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->h.v == hc.v) continue;
if(c->HasLabel() && c->type != Constraint::COMMENT &&
if(c->HasLabel() && c->type != Constraint::Type::COMMENT &&
g->allDimsReference)
{
// When all dimensions are reference, we adjust them to display
@ -339,7 +339,7 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
c->ModifyToSatisfy();
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-
// coincident constraints, and the constraints generated by
// the entities and groups.
@ -366,8 +366,8 @@ void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad) {
for(i = 0; i < SK.constraint.n; i++) {
ConstraintBase *c = &(SK.constraint.elem[i]);
if(c->group.v != g->h.v) continue;
if((c->type == Constraint::POINTS_COINCIDENT && a == 0) ||
(c->type != Constraint::POINTS_COINCIDENT && a == 1))
if((c->type == Constraint::Type::POINTS_COINCIDENT && a == 0) ||
(c->type != Constraint::Type::POINTS_COINCIDENT && a == 1))
{
// Do the constraints in two passes: first everything but
// 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)
{
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
// tells us if the system is inconsistently constrained.
if(!WriteJacobian(0)) {
return System::TOO_MANY_UNKNOWNS;
return SolveResult::TOO_MANY_UNKNOWNS;
}
rankOk = TestRank();
@ -463,7 +463,7 @@ int System::Solve(Group *g, int *dof, List<hConstraint> *bad,
if(!rankOk) {
if(!g->allowRedundant) {
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->free = p->free;
}
return rankOk ? System::SOLVED_OKAY : System::REDUNDANT_OKAY;
return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY;
didnt_converge:
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() {

View File

@ -11,7 +11,7 @@
// link to bring us back home.
//-----------------------------------------------------------------------------
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) {
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.
//-----------------------------------------------------------------------------
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;
}
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) {
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.ScheduleShowTW();
}
@ -77,14 +77,14 @@ void TextWindow::ScreenHowGroupSolved(int link, uint32_t v) {
if(SS.GW.activeGroup.v != v) {
ScreenActivateGroup(link, v);
}
SS.TW.GoToScreen(SCREEN_GROUP_SOLVE_INFO);
SS.TW.GoToScreen(Screen::GROUP_SOLVE_INFO);
SS.TW.shown.group.v = 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) {
SS.TW.GoToScreen(SCREEN_EDIT_VIEW);
SS.TW.GoToScreen(Screen::EDIT_VIEW);
}
void TextWindow::ScreenGoToWebsite(int link, uint32_t v) {
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);
switch(link) {
case 's': g->subtype = Group::ONE_SIDED; break;
case 'S': g->subtype = Group::TWO_SIDED; break;
case 's': g->subtype = Group::Subtype::ONE_SIDED; break;
case 'S': g->subtype = Group::Subtype::TWO_SIDED; break;
case 'k': g->skipFirst = true; 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
// extrusion. If no constraints were added, flip it when we switch between
// union and difference modes to avoid manual work doing the smae.
if(g->meshCombine != (int)v && g->GetNumConstraints() == 0 &&
(v == Group::COMBINE_AS_DIFFERENCE ||
g->meshCombine == Group::COMBINE_AS_DIFFERENCE)) {
if(g->meshCombine != (Group::CombineAs)v && g->GetNumConstraints() == 0 &&
((Group::CombineAs)v == Group::CombineAs::DIFFERENCE ||
g->meshCombine == Group::CombineAs::DIFFERENCE)) {
g->ExtrusionForceVectorTo(g->ExtrusionGetVector().Negated());
}
g->meshCombine = v;
g->meshCombine = (Group::CombineAs)v;
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);
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) {
Group *g = SK.GetGroup(SS.TW.shown.group);
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;
}
void TextWindow::ScreenChangeExprA(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group);
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;
}
void TextWindow::ScreenChangeGroupName(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group);
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;
}
void TextWindow::ScreenChangeGroupScale(int link, uint32_t v) {
Group *g = SK.GetGroup(SS.TW.shown.group);
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;
}
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.
SK.group.RemoveById(hg);
SS.GenerateAll(SolveSpaceUI::GENERATE_ALL);
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
// Reset the graphics window. This will also recreate the default
// group if it was removed.
@ -289,21 +289,21 @@ void TextWindow::ShowGroupInfo() {
g->h.v, &TextWindow::ScreenDeleteGroup);
}
if(g->type == Group::LATHE) {
if(g->type == Group::Type::LATHE) {
Printf(true, " %Ftlathe plane sketch");
} else if(g->type == Group::EXTRUDE || g->type == Group::ROTATE ||
g->type == Group::TRANSLATE)
} else if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::ROTATE ||
g->type == Group::Type::TRANSLATE)
{
if(g->type == Group::EXTRUDE) {
if(g->type == Group::Type::EXTRUDE) {
s = "extrude plane sketch";
} else if(g->type == Group::TRANSLATE) {
} else if(g->type == Group::Type::TRANSLATE) {
s = "translate original sketch";
} else if(g->type == Group::ROTATE) {
} else if(g->type == Group::Type::ROTATE) {
s = "rotate original sketch";
}
Printf(true, " %Ft%s%E", s);
bool one = (g->subtype == Group::ONE_SIDED);
bool one = (g->subtype == Group::Subtype::ONE_SIDED);
Printf(false,
"%Ba %f%Ls%Fd%s one-sided%E "
"%f%LS%Fd%s two-sided%E",
@ -312,8 +312,8 @@ void TextWindow::ShowGroupInfo() {
&TextWindow::ScreenChangeGroupOption,
!one ? RADIO_TRUE : RADIO_FALSE);
if(g->type == Group::ROTATE || g->type == Group::TRANSLATE) {
if(g->subtype == Group::ONE_SIDED) {
if(g->type == Group::Type::ROTATE || g->type == Group::Type::TRANSLATE) {
if(g->subtype == Group::Subtype::ONE_SIDED) {
bool skip = g->skipFirst;
Printf(false,
"%Bd %Ftstart %f%LK%Fd%s with original%E "
@ -326,51 +326,51 @@ void TextWindow::ShowGroupInfo() {
int times = (int)(g->valA);
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",
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(false, "%Ba '%s'", g->linkFileRel.c_str());
Printf(false, "%Bd %Ftscaled by%E %# %Fl%Ll%f%D[change]%E",
g->scale,
&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");
} else if(g->type == Group::DRAWING_WORKPLANE) {
} else if(g->type == Group::Type::DRAWING_WORKPLANE) {
Printf(true, " %Ftsketch in new workplane%E");
} else {
Printf(true, "???");
}
Printf(false, "");
if(g->type == Group::EXTRUDE ||
g->type == Group::LATHE ||
g->type == Group::LINKED)
if(g->type == Group::Type::EXTRUDE ||
g->type == Group::Type::LATHE ||
g->type == Group::Type::LINKED)
{
bool un = (g->meshCombine == Group::COMBINE_AS_UNION);
bool diff = (g->meshCombine == Group::COMBINE_AS_DIFFERENCE);
bool asy = (g->meshCombine == Group::COMBINE_AS_ASSEMBLE);
bool asa = (g->type == Group::LINKED);
bool un = (g->meshCombine == Group::CombineAs::UNION);
bool diff = (g->meshCombine == Group::CombineAs::DIFFERENCE);
bool asy = (g->meshCombine == Group::CombineAs::ASSEMBLE);
bool asa = (g->type == Group::Type::LINKED);
Printf(false, " %Ftsolid model as");
Printf(false, "%Ba %f%D%Lc%Fd%s union%E "
"%f%D%Lc%Fd%s difference%E "
"%f%D%Lc%Fd%s%s%E ",
&TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_UNION,
Group::CombineAs::UNION,
un ? RADIO_TRUE : RADIO_FALSE,
&TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_DIFFERENCE,
Group::CombineAs::DIFFERENCE,
diff ? RADIO_TRUE : RADIO_FALSE,
&TextWindow::ScreenChangeGroupOption,
Group::COMBINE_AS_ASSEMBLE,
Group::CombineAs::ASSEMBLE,
asa ? (asy ? RADIO_TRUE : RADIO_FALSE) : " ",
asa ? " assemble" : "");
if(g->type == Group::EXTRUDE ||
g->type == Group::LATHE)
if(g->type == Group::Type::EXTRUDE ||
g->type == Group::Type::LATHE)
{
Printf(false,
"%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",
g->color.alphaF(),
&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",
&TextWindow::ScreenChangeGroupOption,
g->suppress ? CHECK_TRUE : CHECK_FALSE);
@ -471,36 +471,36 @@ void TextWindow::ScreenAllowRedundant(int link, uint32_t v) {
g->allowRedundant = true;
SS.GenerateAll();
SS.TW.shown.screen = SCREEN_GROUP_INFO;
SS.TW.shown.screen = Screen::GROUP_INFO;
SS.TW.Show();
}
void TextWindow::ShowGroupSolveInfo() {
Group *g = SK.GetGroup(shown.group);
if(g->IsSolvedOkay()) {
// Go back to the default group info screen
shown.screen = SCREEN_GROUP_INFO;
shown.screen = Screen::GROUP_INFO;
Show();
return;
}
Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str());
switch(g->solved.how) {
case System::DIDNT_CONVERGE:
case SolveResult::DIDNT_CONVERGE:
Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints");
Printf(true, "the following constraints are incompatible");
break;
case System::REDUNDANT_DIDNT_CONVERGE:
case SolveResult::REDUNDANT_DIDNT_CONVERGE:
Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints");
Printf(true, "the following constraints are unsatisfied");
break;
case System::REDUNDANT_OKAY:
case SolveResult::REDUNDANT_OKAY:
Printf(true, "%FxSOLVE FAILED!%Fd redundant constraints");
Printf(true, "remove any one of these to fix it");
break;
case System::TOO_MANY_UNKNOWNS:
case SolveResult::TOO_MANY_UNKNOWNS:
Printf(true, "Too many unknowns in a single group!");
return;
}
@ -520,7 +520,7 @@ void TextWindow::ShowGroupSolveInfo() {
Printf(true, "It may be possible to fix the problem ");
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(false, "by %Fl%f%Llallowing redundant constraints%E in ",
&TextWindow::ScreenAllowRedundant);
@ -534,7 +534,7 @@ void TextWindow::ShowGroupSolveInfo() {
// time.
//-----------------------------------------------------------------------------
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;
if(SS.TW.shown.dimIsDistance) {
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);
}
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));
}
void TextWindow::ScreenStepDimGo(int link, uint32_t v) {
@ -567,12 +567,12 @@ void TextWindow::ScreenStepDimGo(int link, uint32_t v) {
}
}
InvalidateGraphics();
SS.TW.GoToScreen(SCREEN_LIST_OF_GROUPS);
SS.TW.GoToScreen(Screen::LIST_OF_GROUPS);
}
void TextWindow::ShowStepDimension() {
Constraint *c = SK.constraint.FindByIdNoOops(shown.constraint);
if(!c) {
shown.screen = SCREEN_LIST_OF_GROUPS;
shown.screen = Screen::LIST_OF_GROUPS;
Show();
return;
}
@ -604,7 +604,7 @@ void TextWindow::ShowStepDimension() {
void TextWindow::ScreenChangeTangentArc(int link, uint32_t v) {
switch(link) {
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));
break;
}
@ -647,7 +647,7 @@ void TextWindow::EditControlDone(const char *s) {
edit.showAgain = false;
switch(edit.meaning) {
case EDIT_TIMES_REPEATED: {
case Edit::TIMES_REPEATED: {
Expr *e = Expr::From(s, true);
if(e) {
SS.UndoRemember();
@ -665,7 +665,7 @@ void TextWindow::EditControlDone(const char *s) {
Group *g = SK.GetGroup(edit.group);
g->valA = ev;
if(g->type == Group::ROTATE) {
if(g->type == Group::Type::ROTATE) {
int i, c = 0;
for(i = 0; i < SK.constraint.n; i++) {
if(SK.constraint.elem[i].group.v == g->h.v) c++;
@ -686,7 +686,7 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_GROUP_NAME: {
case Edit::GROUP_NAME: {
if(!*s) {
Error("Group name cannot be empty");
} else {
@ -697,7 +697,7 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_GROUP_SCALE: {
case Edit::GROUP_SCALE: {
Expr *e = Expr::From(s, true);
if(e) {
double ev = e->Eval();
@ -712,7 +712,7 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_GROUP_COLOR: {
case Edit::GROUP_COLOR: {
Vector rgb;
if(sscanf(s, "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) {
rgb = rgb.ClampWithin(0, 1);
@ -729,7 +729,7 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_GROUP_OPACITY: {
case Edit::GROUP_OPACITY: {
Expr *e = Expr::From(s, true);
if(e) {
double alpha = e->Eval();
@ -745,7 +745,7 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_TTF_TEXT: {
case Edit::TTF_TEXT: {
SS.UndoRemember();
Request *r = SK.request.FindByIdNoOops(edit.request);
if(r) {
@ -755,7 +755,7 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_STEP_DIM_FINISH: {
case Edit::STEP_DIM_FINISH: {
Expr *e = Expr::From(s, true);
if(!e) {
break;
@ -767,11 +767,11 @@ void TextWindow::EditControlDone(const char *s) {
}
break;
}
case EDIT_STEP_DIM_STEPS:
case Edit::STEP_DIM_STEPS:
shown.dimSteps = min(300, max(1, atoi(s)));
break;
case EDIT_TANGENT_ARC_RADIUS: {
case Edit::TANGENT_ARC_RADIUS: {
Expr *e = Expr::From(s, true);
if(!e) break;
if(e->Eval() < LENGTH_EPS) {
@ -797,7 +797,7 @@ void TextWindow::EditControlDone(const char *s) {
if(!edit.showAgain) {
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",
&TextWindow::ScreenUnselectAll);
} 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);
DescribeSelection();
} else {
if(edit.meaning == EDIT_TTF_TEXT) HideEditControl();
if(edit.meaning == Edit::TTF_TEXT) HideEditControl();
ShowHeader(true);
switch(shown.screen) {
default:
shown.screen = SCREEN_LIST_OF_GROUPS;
shown.screen = Screen::LIST_OF_GROUPS;
// fall through
case SCREEN_LIST_OF_GROUPS: ShowListOfGroups(); break;
case SCREEN_GROUP_INFO: ShowGroupInfo(); break;
case SCREEN_GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break;
case SCREEN_CONFIGURATION: ShowConfiguration(); break;
case SCREEN_STEP_DIMENSION: ShowStepDimension(); break;
case SCREEN_LIST_OF_STYLES: ShowListOfStyles(); break;
case SCREEN_STYLE_INFO: ShowStyleInfo(); break;
case SCREEN_PASTE_TRANSFORMED: ShowPasteTransformed(); break;
case SCREEN_EDIT_VIEW: ShowEditView(); break;
case SCREEN_TANGENT_ARC: ShowTangentArc(); break;
case Screen::LIST_OF_GROUPS: ShowListOfGroups(); break;
case Screen::GROUP_INFO: ShowGroupInfo(); break;
case Screen::GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break;
case Screen::CONFIGURATION: ShowConfiguration(); break;
case Screen::STEP_DIMENSION: ShowStepDimension(); break;
case Screen::LIST_OF_STYLES: ShowListOfStyles(); break;
case Screen::STYLE_INFO: ShowStyleInfo(); break;
case Screen::PASTE_TRANSFORMED: ShowPasteTransformed(); break;
case Screen::EDIT_VIEW: ShowEditView(); break;
case Screen::TANGENT_ARC: ShowTangentArc(); break;
}
}
Printf(false, "");
@ -344,7 +344,7 @@ void TextWindow::TimerCallback()
InvalidateText();
}
void TextWindow::DrawOrHitTestIcons(int how, double mx, double my)
void TextWindow::DrawOrHitTestIcons(TextWindow::DrawOrHitHow how, double mx, double my)
{
int 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());
}
bool TextWindow::DrawOrHitTestColorPicker(int how, bool leftDown,
bool TextWindow::DrawOrHitTestColorPicker(DrawOrHitHow how, bool leftDown,
double x, double y)
{
bool mousePointerAsHand = false;
@ -933,7 +933,7 @@ void TextWindow::Paint() {
SS.GW.GroupSelection();
// Make sure this test agrees with test to determine which screen is drawn
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;
y -= scrollPos*(LINE_HEIGHT/2);

View File

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

424
src/ui.h
View File

@ -8,6 +8,144 @@
#ifndef __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 {
public:
enum {
@ -76,12 +214,12 @@ public:
void MouseLeave();
void ScrollbarEvent(int newPos);
enum {
enum DrawOrHitHow : uint32_t {
PAINT = 0,
HOVER = 1,
CLICK = 2
};
void DrawOrHitTestIcons(int how, double mx, double my);
void DrawOrHitTestIcons(DrawOrHitHow how, double mx, double my);
void TimerCallback();
Point2d oldMousePos;
HideShowIcon *hoveredIcon, *tooltippedIcon;
@ -90,7 +228,7 @@ public:
uint8_t *HsvPattern2d();
uint8_t *HsvPattern1d(double h, double s);
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 MakeColorTable(const Color *in, float *out);
@ -100,20 +238,20 @@ public:
void Show();
// State for the screen that we are showing in the text window.
enum {
SCREEN_LIST_OF_GROUPS = 0,
SCREEN_GROUP_INFO = 1,
SCREEN_GROUP_SOLVE_INFO = 2,
SCREEN_CONFIGURATION = 3,
SCREEN_STEP_DIMENSION = 4,
SCREEN_LIST_OF_STYLES = 5,
SCREEN_STYLE_INFO = 6,
SCREEN_PASTE_TRANSFORMED = 7,
SCREEN_EDIT_VIEW = 8,
SCREEN_TANGENT_ARC = 9
enum class Screen : uint32_t {
LIST_OF_GROUPS = 0,
GROUP_INFO = 1,
GROUP_SOLVE_INFO = 2,
CONFIGURATION = 3,
STEP_DIMENSION = 4,
LIST_OF_STYLES = 5,
STYLE_INFO = 6,
PASTE_TRANSFORMED = 7,
EDIT_VIEW = 8,
TANGENT_ARC = 9
};
typedef struct {
int screen;
Screen screen;
hGroup group;
hStyle style;
@ -133,61 +271,61 @@ public:
} ShownState;
ShownState shown;
enum {
EDIT_NOTHING = 0,
enum class Edit : uint32_t {
NOTHING = 0,
// For multiple groups
EDIT_TIMES_REPEATED = 1,
EDIT_GROUP_NAME = 2,
EDIT_GROUP_SCALE = 3,
EDIT_GROUP_COLOR = 4,
EDIT_GROUP_OPACITY = 5,
TIMES_REPEATED = 1,
GROUP_NAME = 2,
GROUP_SCALE = 3,
GROUP_COLOR = 4,
GROUP_OPACITY = 5,
// For the configuraiton screen
EDIT_LIGHT_DIRECTION = 100,
EDIT_LIGHT_INTENSITY = 101,
EDIT_COLOR = 102,
EDIT_CHORD_TOLERANCE = 103,
EDIT_MAX_SEGMENTS = 104,
EDIT_CAMERA_TANGENT = 105,
EDIT_GRID_SPACING = 106,
EDIT_DIGITS_AFTER_DECIMAL = 107,
EDIT_EXPORT_SCALE = 108,
EDIT_EXPORT_OFFSET = 109,
EDIT_CANVAS_SIZE = 110,
EDIT_G_CODE_DEPTH = 120,
EDIT_G_CODE_PASSES = 121,
EDIT_G_CODE_FEED = 122,
EDIT_G_CODE_PLUNGE_FEED = 123,
EDIT_AUTOSAVE_INTERVAL = 124,
LIGHT_DIRECTION = 100,
LIGHT_INTENSITY = 101,
COLOR = 102,
CHORD_TOLERANCE = 103,
MAX_SEGMENTS = 104,
CAMERA_TANGENT = 105,
GRID_SPACING = 106,
DIGITS_AFTER_DECIMAL = 107,
EXPORT_SCALE = 108,
EXPORT_OFFSET = 109,
CANVAS_SIZE = 110,
G_CODE_DEPTH = 120,
G_CODE_PASSES = 121,
G_CODE_FEED = 122,
G_CODE_PLUNGE_FEED = 123,
AUTOSAVE_INTERVAL = 124,
// For TTF text
EDIT_TTF_TEXT = 300,
TTF_TEXT = 300,
// For the step dimension screen
EDIT_STEP_DIM_FINISH = 400,
EDIT_STEP_DIM_STEPS = 401,
STEP_DIM_FINISH = 400,
STEP_DIM_STEPS = 401,
// For the styles stuff
EDIT_STYLE_WIDTH = 500,
EDIT_STYLE_TEXT_HEIGHT = 501,
EDIT_STYLE_TEXT_ANGLE = 502,
EDIT_STYLE_COLOR = 503,
EDIT_STYLE_FILL_COLOR = 504,
EDIT_STYLE_NAME = 505,
EDIT_BACKGROUND_COLOR = 506,
EDIT_BACKGROUND_IMG_SCALE = 507,
EDIT_STYLE_STIPPLE_PERIOD = 508,
STYLE_WIDTH = 500,
STYLE_TEXT_HEIGHT = 501,
STYLE_TEXT_ANGLE = 502,
STYLE_COLOR = 503,
STYLE_FILL_COLOR = 504,
STYLE_NAME = 505,
BACKGROUND_COLOR = 506,
BACKGROUND_IMG_SCALE = 507,
STYLE_STIPPLE_PERIOD = 508,
// For paste transforming
EDIT_PASTE_TIMES_REPEATED = 600,
EDIT_PASTE_ANGLE = 601,
EDIT_PASTE_SCALE = 602,
PASTE_TIMES_REPEATED = 600,
PASTE_ANGLE = 601,
PASTE_SCALE = 602,
// For view
EDIT_VIEW_SCALE = 700,
EDIT_VIEW_ORIGIN = 701,
EDIT_VIEW_PROJ_RIGHT = 702,
EDIT_VIEW_PROJ_UP = 703,
VIEW_SCALE = 700,
VIEW_ORIGIN = 701,
VIEW_PROJ_RIGHT = 702,
VIEW_PROJ_UP = 703,
// For tangent arc
EDIT_TANGENT_ARC_RADIUS = 800
TANGENT_ARC_RADIUS = 800
};
struct {
bool showAgain;
int meaning;
Edit meaning;
int i;
hGroup group;
hRequest request;
@ -231,7 +369,7 @@ public:
// Special screen, based on selection
void DescribeSelection();
void GoToScreen(int screen);
void GoToScreen(Screen screen);
// All of these are callbacks from the GUI code; first from when
// we're describing an entity
@ -335,110 +473,7 @@ class GraphicsWindow {
public:
void Init();
// This table describes the top-level menus in the graphics winodw.
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);
typedef void MenuHandler(Command id);
enum {
ESCAPE_KEY = 27,
DELETE_KEY = 127,
@ -448,27 +483,27 @@ public:
SHIFT_MASK = 0x100,
CTRL_MASK = 0x200
};
enum MenuItemKind {
MENU_ITEM_NORMAL = 0,
MENU_ITEM_CHECK,
MENU_ITEM_RADIO
enum class MenuKind : uint32_t {
NORMAL = 0,
CHECK,
RADIO
};
typedef struct {
int level; // 0 == on menu bar, 1 == one level down
const char *label; // or NULL for a separator
int id; // unique ID
Command id; // unique ID
int accel; // keyboard accelerator
MenuItemKind kind;
MenuKind kind;
MenuHandler *fn;
} MenuEntry;
static const MenuEntry menu[];
static void MenuView(int id);
static void MenuEdit(int id);
static void MenuRequest(int id);
static void MenuView(Command id);
static void MenuEdit(Command id);
static void MenuRequest(Command id);
void DeleteSelection();
void CopySelection();
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.
double width, height;
@ -549,12 +584,6 @@ public:
DRAGGING_MARQUEE = 0x0f000009
};
enum SuggestedConstraint {
SUGGESTED_NONE = 0,
SUGGESTED_HORIZONTAL = Constraint::HORIZONTAL,
SUGGESTED_VERTICAL = Constraint::VERTICAL,
};
struct {
int operation;
@ -567,19 +596,19 @@ public:
const char *description;
SuggestedConstraint suggestion;
Constraint::Type suggestion;
} pending;
void ClearPending();
// The constraint that is being edited with the on-screen textbox.
hConstraint constraintBeingEdited;
SuggestedConstraint SuggestLineConstraint(hRequest lineSegment);
ConstraintBase::Type SuggestLineConstraint(hRequest lineSegment);
Vector SnapToGrid(Vector p);
bool ConstrainPointByHovered(hEntity pt);
void DeleteTaggedRequests();
hRequest AddRequest(int type, bool rememberForUndo);
hRequest AddRequest(int type);
hRequest AddRequest(Request::Type type, bool rememberForUndo);
hRequest AddRequest(Request::Type type);
class ParametricCurve {
public:
@ -666,38 +695,17 @@ public:
void SelectByMarquee();
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();
int64_t contextMenuCancelTime;
// 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();
bool ToolbarMouseMoved(int x, int y);
bool ToolbarMouseDown(int x, int y);
static void TimerCallback();
int toolbarHovered;
int toolbarTooltipped;
Command toolbarHovered;
Command toolbarTooltipped;
int toolbarMouseX, toolbarMouseY;
// This sets what gets displayed.

View File

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

View File

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