2013-07-28 22:08:34 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Given a constraint, draw a graphical and user-selectable representation
|
|
|
|
// of that constraint on-screen. We can either draw with gl, or compute the
|
|
|
|
// distance from a point (the location of the mouse pointer) to the lines
|
|
|
|
// that we would have drawn, for selection.
|
|
|
|
//
|
|
|
|
// Copyright 2008-2013 Jonathan Westhues.
|
|
|
|
//-----------------------------------------------------------------------------
|
2008-04-14 10:28:32 +00:00
|
|
|
#include "solvespace.h"
|
|
|
|
|
2008-04-21 08:16:38 +00:00
|
|
|
void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
|
|
|
|
if(dogd.drawing) {
|
2016-05-07 10:54:44 +00:00
|
|
|
hStyle hs = GetStyle();
|
2009-09-24 15:52:48 +00:00
|
|
|
|
2009-07-03 20:55:57 +00:00
|
|
|
if(dogd.sel) {
|
2009-09-24 15:52:48 +00:00
|
|
|
dogd.sel->AddEdge(a, b, hs.v);
|
2009-07-03 20:55:57 +00:00
|
|
|
} else {
|
2016-02-21 19:07:58 +00:00
|
|
|
if(Style::Width(hs) >= 3.0) {
|
2013-10-22 04:45:06 +00:00
|
|
|
ssglFatLine(a, b, Style::Width(hs) / SS.GW.scale);
|
2009-09-24 15:52:48 +00:00
|
|
|
} else {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2013-10-22 04:45:06 +00:00
|
|
|
ssglVertex3v(a);
|
|
|
|
ssglVertex3v(b);
|
2009-09-24 15:52:48 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
2009-07-03 20:55:57 +00:00
|
|
|
}
|
2008-04-21 08:16:38 +00:00
|
|
|
} else {
|
|
|
|
Point2d ap = SS.GW.ProjectPoint(a);
|
|
|
|
Point2d bp = SS.GW.ProjectPoint(b);
|
|
|
|
|
2016-05-25 12:08:19 +00:00
|
|
|
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true);
|
2008-04-21 08:16:38 +00:00
|
|
|
dogd.dmin = min(dogd.dmin, d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-03 20:55:57 +00:00
|
|
|
static void LineCallback(void *fndata, Vector a, Vector b)
|
|
|
|
{
|
|
|
|
Constraint *c = (Constraint *)fndata;
|
|
|
|
c->LineDrawOrGetDistance(a, b);
|
|
|
|
}
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
std::string Constraint::Label() const {
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string result;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::ANGLE) {
|
2016-04-16 01:13:06 +00:00
|
|
|
if(valA == floor(valA)) {
|
|
|
|
result = ssprintf("%.0f°", valA);
|
|
|
|
} else {
|
|
|
|
result = ssprintf("%.2f°", valA);
|
|
|
|
}
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
} else if(type == Type::LENGTH_RATIO) {
|
2015-11-06 08:40:12 +00:00
|
|
|
result = ssprintf("%.3f:1", valA);
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
} else if(type == Type::COMMENT) {
|
2015-11-06 08:40:12 +00:00
|
|
|
result = comment;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
} else if(type == Type::DIAMETER) {
|
2015-03-22 13:07:49 +00:00
|
|
|
if(!other) {
|
2016-04-16 01:07:35 +00:00
|
|
|
result = "⌀" + SS.MmToString(valA);
|
2015-03-22 13:07:49 +00:00
|
|
|
} else {
|
2015-11-06 08:40:12 +00:00
|
|
|
result = "R" + SS.MmToString(valA / 2);
|
2015-03-22 13:07:49 +00:00
|
|
|
}
|
2008-06-11 04:22:52 +00:00
|
|
|
} else {
|
2008-06-14 08:43:38 +00:00
|
|
|
// valA has units of distance
|
2015-11-06 08:40:12 +00:00
|
|
|
result = SS.MmToString(fabs(valA));
|
2008-06-11 04:22:52 +00:00
|
|
|
}
|
|
|
|
if(reference) {
|
2015-11-06 08:40:12 +00:00
|
|
|
result += " REF";
|
2008-06-11 04:22:52 +00:00
|
|
|
}
|
2015-11-06 08:40:12 +00:00
|
|
|
return result;
|
2008-06-11 04:22:52 +00:00
|
|
|
}
|
|
|
|
|
2008-05-07 08:19:37 +00:00
|
|
|
void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
|
2016-05-07 10:54:44 +00:00
|
|
|
hStyle hs = GetStyle();
|
2016-02-21 19:07:58 +00:00
|
|
|
double th = Style::TextHeight(hs);
|
2009-09-24 15:52:48 +00:00
|
|
|
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string s = Label();
|
2016-02-05 09:28:29 +00:00
|
|
|
double swidth = ssglStrWidth(s, th),
|
2016-04-12 13:38:09 +00:00
|
|
|
sheight = ssglStrCapHeight(th);
|
2009-09-24 15:52:48 +00:00
|
|
|
|
|
|
|
// By default, the reference is from the center; but the style could
|
2009-09-29 11:35:19 +00:00
|
|
|
// specify otherwise if one is present, and it could also specify a
|
|
|
|
// rotation.
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::COMMENT && disp.style.v) {
|
2009-09-29 11:35:19 +00:00
|
|
|
Style *st = Style::Get(disp.style);
|
|
|
|
// rotation first
|
|
|
|
double rads = st->textAngle*PI/180;
|
|
|
|
double c = cos(rads), s = sin(rads);
|
|
|
|
Vector pr = gr, pu = gu;
|
|
|
|
gr = pr.ScaledBy( c).Plus(pu.ScaledBy(s));
|
|
|
|
gu = pr.ScaledBy(-s).Plus(pu.ScaledBy(c));
|
|
|
|
// then origin
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
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));
|
2009-09-24 15:52:48 +00:00
|
|
|
}
|
|
|
|
|
2008-05-07 08:19:37 +00:00
|
|
|
if(labelPos) {
|
|
|
|
// labelPos is from the top left corner (for the text box used to
|
|
|
|
// edit things), but ref is from the center.
|
2008-06-12 08:58:58 +00:00
|
|
|
*labelPos = ref.Minus(gr.WithMagnitude(swidth/2)).Minus(
|
|
|
|
gu.WithMagnitude(sheight/2));
|
2008-05-07 08:19:37 +00:00
|
|
|
}
|
|
|
|
|
2009-09-24 15:52:48 +00:00
|
|
|
|
2008-05-07 08:19:37 +00:00
|
|
|
if(dogd.drawing) {
|
2016-05-21 05:18:00 +00:00
|
|
|
ssglWriteTextRefCenter(s, th, ref, gr, gu, LineCallback, (void *)this);
|
2008-05-07 08:19:37 +00:00
|
|
|
} else {
|
2008-06-12 08:58:58 +00:00
|
|
|
double l = swidth/2 - sheight/2;
|
2008-07-06 07:56:24 +00:00
|
|
|
l = max(l, 5/SS.GW.scale);
|
2008-06-12 08:58:58 +00:00
|
|
|
Point2d a = SS.GW.ProjectPoint(ref.Minus(gr.WithMagnitude(l)));
|
|
|
|
Point2d b = SS.GW.ProjectPoint(ref.Plus (gr.WithMagnitude(l)));
|
2016-05-25 12:08:19 +00:00
|
|
|
double d = dogd.mp.DistanceToLine(a, b.Minus(a), /*asSegment=*/true);
|
2008-06-12 08:58:58 +00:00
|
|
|
|
2009-09-24 15:52:48 +00:00
|
|
|
dogd.dmin = min(dogd.dmin, d - (th / 2));
|
2008-05-07 08:19:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-27 18:15:06 +00:00
|
|
|
void Constraint::StippledLine(Vector a, Vector b) {
|
2008-05-08 07:30:30 +00:00
|
|
|
glLineStipple(4, 0x5555);
|
|
|
|
glEnable(GL_LINE_STIPPLE);
|
2010-01-27 18:15:06 +00:00
|
|
|
LineDrawOrGetDistance(a, b);
|
2008-05-08 07:30:30 +00:00
|
|
|
glDisable(GL_LINE_STIPPLE);
|
2010-01-27 18:15:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Constraint::DoProjectedPoint(Vector *r) {
|
|
|
|
Vector p = r->ProjectInto(workplane);
|
|
|
|
StippledLine(p, *r);
|
2008-05-08 07:30:30 +00:00
|
|
|
*r = p;
|
|
|
|
}
|
|
|
|
|
2009-09-03 08:13:09 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// There is a rectangular box, aligned to our display axes (projRight, projUp)
|
|
|
|
// centered at ref. This is where a dimension label will be drawn. We want to
|
|
|
|
// draw a line from A to B. If that line would intersect the label box, then
|
|
|
|
// trim the line to leave a gap for it, and return zero. If not, then extend
|
|
|
|
// the line to almost meet the box, and return either positive or negative,
|
|
|
|
// depending whether that extension was from A or from B.
|
|
|
|
//-----------------------------------------------------------------------------
|
2016-04-13 02:45:52 +00:00
|
|
|
int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend) {
|
2016-05-07 10:54:44 +00:00
|
|
|
hStyle hs = GetStyle();
|
2016-02-21 19:07:58 +00:00
|
|
|
double th = Style::TextHeight(hs);
|
2009-09-03 08:13:09 +00:00
|
|
|
Vector gu = SS.GW.projUp.WithMagnitude(1),
|
|
|
|
gr = SS.GW.projRight.WithMagnitude(1);
|
|
|
|
|
|
|
|
double pixels = 1.0 / SS.GW.scale;
|
2015-11-06 08:40:12 +00:00
|
|
|
std::string s = Label();
|
2016-02-21 19:07:58 +00:00
|
|
|
double swidth = ssglStrWidth(s, th) + 4*pixels,
|
2016-04-12 13:38:09 +00:00
|
|
|
sheight = ssglStrCapHeight(th) + 8*pixels;
|
2009-09-03 08:13:09 +00:00
|
|
|
|
2016-04-13 02:45:52 +00:00
|
|
|
return DoLineTrimmedAgainstBox(ref, a, b, extend, gr, gu, swidth, sheight);
|
|
|
|
}
|
|
|
|
|
|
|
|
int Constraint::DoLineTrimmedAgainstBox(Vector ref, Vector a, Vector b, bool extend,
|
|
|
|
Vector gr, Vector gu, double swidth, double sheight) {
|
2009-09-03 08:13:09 +00:00
|
|
|
struct {
|
|
|
|
Vector n;
|
|
|
|
double d;
|
|
|
|
} planes[4];
|
|
|
|
// reference pos is the center of box occupied by text; build a rectangle
|
|
|
|
// around that, aligned to axes gr and gu, from four planes will all four
|
|
|
|
// normals pointing inward
|
|
|
|
planes[0].n = gu.ScaledBy(-1); planes[0].d = -(gu.Dot(ref) + sheight/2);
|
|
|
|
planes[1].n = gu; planes[1].d = gu.Dot(ref) - sheight/2;
|
|
|
|
planes[2].n = gr; planes[2].d = gr.Dot(ref) - swidth/2;
|
|
|
|
planes[3].n = gr.ScaledBy(-1); planes[3].d = -(gr.Dot(ref) + swidth/2);
|
|
|
|
|
|
|
|
double tmin = VERY_POSITIVE, tmax = VERY_NEGATIVE;
|
|
|
|
Vector dl = b.Minus(a);
|
|
|
|
|
|
|
|
for(int i = 0; i < 4; i++) {
|
|
|
|
bool parallel;
|
|
|
|
Vector p = Vector::AtIntersectionOfPlaneAndLine(
|
|
|
|
planes[i].n, planes[i].d,
|
|
|
|
a, b, ¶llel);
|
|
|
|
if(parallel) continue;
|
|
|
|
|
|
|
|
int j;
|
|
|
|
for(j = 0; j < 4; j++) {
|
|
|
|
double d = (planes[j].n).Dot(p) - planes[j].d;
|
|
|
|
if(d < -LENGTH_EPS) break;
|
|
|
|
}
|
|
|
|
if(j < 4) continue;
|
|
|
|
|
|
|
|
double t = (p.Minus(a)).DivPivoting(dl);
|
|
|
|
tmin = min(t, tmin);
|
|
|
|
tmax = max(t, tmax);
|
|
|
|
}
|
|
|
|
|
2016-04-13 02:45:52 +00:00
|
|
|
// Both in range; so there's pieces of the line on both sides of the label box.
|
|
|
|
if(tmin >= 0.0 && tmin <= 1.0 && tmax >= 0.0 && tmax <= 1.0) {
|
2009-09-03 08:13:09 +00:00
|
|
|
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
|
|
|
|
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
|
2016-04-13 02:45:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only one intersection in range; so the box is right on top of the endpoint
|
|
|
|
if(tmin >= 0.0 && tmin <= 1.0) {
|
2009-09-03 08:13:09 +00:00
|
|
|
LineDrawOrGetDistance(a, a.Plus(dl.ScaledBy(tmin)));
|
2016-04-13 02:45:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Likewise.
|
|
|
|
if(tmax >= 0.0 && tmax <= 1.0) {
|
2009-09-03 08:13:09 +00:00
|
|
|
LineDrawOrGetDistance(a.Plus(dl.ScaledBy(tmax)), b);
|
2016-04-13 02:45:52 +00:00
|
|
|
return 0;
|
2009-09-03 08:13:09 +00:00
|
|
|
}
|
2016-04-13 02:45:52 +00:00
|
|
|
|
|
|
|
// The line does not intersect the label; so the line should get
|
|
|
|
// extended to just barely meet the label.
|
2009-09-03 08:13:09 +00:00
|
|
|
// 0 means the label lies within the line, negative means it's outside
|
|
|
|
// and closer to b, positive means outside and closer to a.
|
2016-04-13 02:45:52 +00:00
|
|
|
if(tmax < 0.0) {
|
|
|
|
if(extend) a = a.Plus(dl.ScaledBy(tmax));
|
|
|
|
LineDrawOrGetDistance(a, b);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(tmin > 1.0) {
|
|
|
|
if(extend) b = a.Plus(dl.ScaledBy(tmin));
|
|
|
|
LineDrawOrGetDistance(a, b);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This will happen if the entire line lies within the box.
|
|
|
|
return 0;
|
2009-09-03 08:13:09 +00:00
|
|
|
}
|
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
void Constraint::DoArrow(Vector p, Vector dir, Vector n, double width, double angle, double da) {
|
|
|
|
dir = dir.WithMagnitude(width / cos(angle));
|
|
|
|
dir = dir.RotatedAbout(n, da);
|
|
|
|
LineDrawOrGetDistance(p, p.Plus(dir.RotatedAbout(n, angle)));
|
|
|
|
LineDrawOrGetDistance(p, p.Plus(dir.RotatedAbout(n, -angle)));
|
|
|
|
}
|
|
|
|
|
2009-09-03 08:13:09 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Draw a line with arrows on both ends, and possibly a gap in the middle for
|
|
|
|
// the dimension. We will use these for most length dimensions. The length
|
|
|
|
// being dimensioned is from A to B; but those points get extended perpendicular
|
|
|
|
// to the line AB, until the line between the extensions crosses ref (the
|
|
|
|
// center of the label).
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void Constraint::DoLineWithArrows(Vector ref, Vector a, Vector b,
|
|
|
|
bool onlyOneExt)
|
|
|
|
{
|
|
|
|
double pixels = 1.0 / SS.GW.scale;
|
|
|
|
|
|
|
|
Vector ab = a.Minus(b);
|
|
|
|
Vector ar = a.Minus(ref);
|
|
|
|
// Normal to a plane containing the line and the label origin.
|
|
|
|
Vector n = ab.Cross(ar);
|
|
|
|
// Within that plane, and normal to the line AB; so that's our extension
|
|
|
|
// line.
|
|
|
|
Vector out = ab.Cross(n).WithMagnitude(1);
|
|
|
|
out = out.ScaledBy(-out.Dot(ar));
|
|
|
|
|
|
|
|
Vector ae = a.Plus(out), be = b.Plus(out);
|
|
|
|
|
|
|
|
// Extension lines extend 10 pixels beyond where the arrows get
|
|
|
|
// drawn (which is at the same offset perpendicular from AB as the
|
|
|
|
// label).
|
|
|
|
LineDrawOrGetDistance(a, ae.Plus(out.WithMagnitude(10*pixels)));
|
|
|
|
if(!onlyOneExt) {
|
|
|
|
LineDrawOrGetDistance(b, be.Plus(out.WithMagnitude(10*pixels)));
|
|
|
|
}
|
|
|
|
|
|
|
|
int within = DoLineTrimmedAgainstBox(ref, ae, be);
|
|
|
|
|
|
|
|
// Arrow heads are 13 pixels long, with an 18 degree half-angle.
|
|
|
|
double theta = 18*PI/180;
|
|
|
|
Vector arrow = (be.Minus(ae)).WithMagnitude(13*pixels);
|
|
|
|
|
|
|
|
if(within != 0) {
|
|
|
|
arrow = arrow.ScaledBy(-1);
|
|
|
|
Vector seg = (be.Minus(ae)).WithMagnitude(18*pixels);
|
|
|
|
if(within < 0) LineDrawOrGetDistance(ae, ae.Minus(seg));
|
|
|
|
if(within > 0) LineDrawOrGetDistance(be, be.Plus(seg));
|
|
|
|
}
|
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
DoArrow(ae, arrow, n, 13.0 * pixels, theta, 0.0);
|
|
|
|
DoArrow(be, arrow.Negated(), n, 13.0 * pixels, theta, 0.0);
|
2009-09-03 08:13:09 +00:00
|
|
|
}
|
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
void Constraint::DoEqualLenTicks(Vector a, Vector b, Vector gn, Vector *refp) {
|
2008-06-14 11:16:14 +00:00
|
|
|
Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3));
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refp) *refp = m;
|
2008-06-14 11:16:14 +00:00
|
|
|
Vector ab = a.Minus(b);
|
|
|
|
Vector n = (gn.Cross(ab)).WithMagnitude(10/SS.GW.scale);
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2008-06-14 11:16:14 +00:00
|
|
|
LineDrawOrGetDistance(m.Minus(n), m.Plus(n));
|
|
|
|
}
|
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
void Constraint::DoEqualRadiusTicks(hEntity he, Vector *refp) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *circ = SK.GetEntity(he);
|
2009-01-08 17:22:59 +00:00
|
|
|
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector center = SK.GetEntity(circ->point[0])->PointGetNum();
|
2009-01-08 17:22:59 +00:00
|
|
|
double r = circ->CircleGetRadiusNum();
|
|
|
|
Quaternion q = circ->Normal()->NormalGetNum();
|
|
|
|
Vector u = q.RotationU(), v = q.RotationV();
|
|
|
|
|
|
|
|
double theta;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(circ->type == Entity::Type::CIRCLE) {
|
2009-01-08 17:22:59 +00:00
|
|
|
theta = PI/2;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
} else if(circ->type == Entity::Type::ARC_OF_CIRCLE) {
|
2009-01-08 17:22:59 +00:00
|
|
|
double thetaa, thetab, dtheta;
|
|
|
|
circ->ArcGetAngles(&thetaa, &thetab, &dtheta);
|
|
|
|
theta = thetaa + dtheta/2;
|
2016-05-18 22:51:36 +00:00
|
|
|
} else ssassert(false, "Unexpected entity type");
|
2009-01-08 17:22:59 +00:00
|
|
|
|
|
|
|
Vector d = u.ScaledBy(cos(theta)).Plus(v.ScaledBy(sin(theta)));
|
|
|
|
d = d.ScaledBy(r);
|
|
|
|
Vector p = center.Plus(d);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refp) *refp = p;
|
2009-01-08 17:22:59 +00:00
|
|
|
Vector tick = d.WithMagnitude(10/SS.GW.scale);
|
|
|
|
LineDrawOrGetDistance(p.Plus(tick), p.Minus(tick));
|
|
|
|
}
|
|
|
|
|
2008-07-20 12:24:43 +00:00
|
|
|
void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
2016-04-13 02:45:52 +00:00
|
|
|
Vector offset, Vector *ref, bool trim)
|
2008-07-20 12:24:43 +00:00
|
|
|
{
|
2016-04-13 02:45:52 +00:00
|
|
|
Vector gr = SS.GW.projRight.ScaledBy(1.0);
|
|
|
|
Vector gu = SS.GW.projUp.ScaledBy(1.0);
|
2008-07-20 12:24:43 +00:00
|
|
|
|
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
a0 = a0.ProjectInto(workplane);
|
|
|
|
b0 = b0.ProjectInto(workplane);
|
|
|
|
da = da.ProjectVectorInto(workplane);
|
|
|
|
db = db.ProjectVectorInto(workplane);
|
|
|
|
}
|
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
double px = 1.0 / SS.GW.scale;
|
|
|
|
Vector a1 = a0.Plus(da);
|
|
|
|
Vector b1 = b0.Plus(db);
|
|
|
|
|
2009-01-03 12:27:33 +00:00
|
|
|
bool skew;
|
2015-03-29 00:30:52 +00:00
|
|
|
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da),
|
2009-01-03 12:27:33 +00:00
|
|
|
b0, b0.Plus(db), &skew);
|
|
|
|
|
|
|
|
if(!skew) {
|
2008-07-20 12:24:43 +00:00
|
|
|
*ref = pi.Plus(offset);
|
2009-01-03 12:27:33 +00:00
|
|
|
// We draw in a coordinate system centered at the intersection point.
|
|
|
|
// One basis vector is da, and the other is normal to da and in
|
|
|
|
// the plane that contains our lines (so normal to its normal).
|
2016-04-15 11:57:44 +00:00
|
|
|
da = da.WithMagnitude(1);
|
|
|
|
db = db.WithMagnitude(1);
|
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
Vector norm = da.Cross(db);
|
2016-04-15 11:57:44 +00:00
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
Vector dna = norm.Cross(da).WithMagnitude(1.0);
|
2016-04-15 11:57:44 +00:00
|
|
|
Vector dnb = norm.Cross(db).WithMagnitude(1.0);
|
2009-01-03 12:27:33 +00:00
|
|
|
|
2016-04-15 11:57:44 +00:00
|
|
|
// da and db magnitudes are 1.0
|
|
|
|
double thetaf = acos(da.Dot(db));
|
2008-07-20 12:24:43 +00:00
|
|
|
|
2016-04-15 11:57:44 +00:00
|
|
|
// Calculate median
|
2008-07-20 12:24:43 +00:00
|
|
|
Vector m = da.ScaledBy(cos(thetaf/2)).Plus(
|
|
|
|
dna.ScaledBy(sin(thetaf/2)));
|
2016-04-15 11:57:44 +00:00
|
|
|
Vector rm = (*ref).Minus(pi);
|
|
|
|
|
|
|
|
// Test which side we have to place an arc
|
2008-07-20 12:24:43 +00:00
|
|
|
if(m.Dot(rm) < 0) {
|
|
|
|
da = da.ScaledBy(-1); dna = dna.ScaledBy(-1);
|
2016-04-15 11:57:44 +00:00
|
|
|
db = db.ScaledBy(-1); dnb = dnb.ScaledBy(-1);
|
2008-07-20 12:24:43 +00:00
|
|
|
}
|
|
|
|
|
2016-04-15 11:57:44 +00:00
|
|
|
double rda = rm.Dot(da), rdna = rm.Dot(dna);
|
|
|
|
|
|
|
|
// Introduce minimal arc radius in pixels
|
|
|
|
double r = max(sqrt(rda*rda + rdna*rdna), 15.0 * px);
|
|
|
|
|
2016-04-13 02:45:52 +00:00
|
|
|
hStyle hs = disp.style;
|
|
|
|
if(hs.v == 0) hs.v = Style::CONSTRAINT;
|
|
|
|
double th = Style::TextHeight(hs);
|
|
|
|
double swidth = ssglStrWidth(Label(), th) + 4.0 * px;
|
|
|
|
double sheight = ssglStrCapHeight(th) + 8.0 * px;
|
|
|
|
double textR = sqrt(swidth * swidth + sheight * sheight) / 2.0;
|
|
|
|
*ref = pi.Plus(rm.WithMagnitude(std::max(rm.Magnitude(), 15 * px + textR)));
|
|
|
|
|
2016-04-16 11:58:23 +00:00
|
|
|
// Arrow points
|
|
|
|
Vector apa = da. ScaledBy(r).Plus(pi);
|
|
|
|
Vector apb = da. ScaledBy(r*cos(thetaf)).Plus(
|
|
|
|
dna.ScaledBy(r*sin(thetaf))).Plus(pi);
|
|
|
|
|
|
|
|
double arrowW = 13 * px;
|
|
|
|
double arrowA = 18.0 * PI / 180.0;
|
|
|
|
bool arrowVisible = apb.Minus(apa).Magnitude() > 2.5 * arrowW;
|
|
|
|
// Arrow reversing indicator
|
|
|
|
bool arrowRev = false;
|
|
|
|
|
|
|
|
// The minimal extension length in angular representation
|
|
|
|
double extAngle = 18 * px / r;
|
|
|
|
|
|
|
|
// Arc additional angle
|
2016-04-15 11:57:44 +00:00
|
|
|
double addAngle = 0.0;
|
2016-04-16 11:58:23 +00:00
|
|
|
// Arc start angle
|
|
|
|
double startAngle = 0.0;
|
2016-04-11 14:21:41 +00:00
|
|
|
|
2016-04-15 11:57:44 +00:00
|
|
|
// Arc extension to db.
|
|
|
|
// We have just enlarge angle value.
|
|
|
|
if(HasLabel() && rm.Dot(dnb) > 0.0) {
|
|
|
|
// rm direction projected to plane with u = da, v = dna
|
|
|
|
Vector rmp = da.ScaledBy(rda).Plus(dna.ScaledBy(rdna)).WithMagnitude(1.0);
|
|
|
|
// rmp and db magnitudes are 1.0
|
2016-04-16 11:58:23 +00:00
|
|
|
addAngle = std::max(acos(rmp.Dot(db)), extAngle);
|
2016-04-15 11:57:44 +00:00
|
|
|
|
2016-04-16 11:58:23 +00:00
|
|
|
if(arrowVisible) {
|
|
|
|
startAngle = -extAngle;
|
|
|
|
addAngle += extAngle;
|
|
|
|
arrowRev = true;
|
|
|
|
}
|
|
|
|
}
|
2016-04-15 11:57:44 +00:00
|
|
|
|
|
|
|
// Arc extension to da.
|
|
|
|
// We are enlarge angle value and rewrite basis to align along rm projection.
|
|
|
|
if(HasLabel() && rm.Dot(dna) < 0.0) {
|
|
|
|
// rm direction projected to plane with u = da, v = dna
|
|
|
|
Vector rmp = da.ScaledBy(rda).Plus(dna.ScaledBy(rdna)).WithMagnitude(1.0);
|
|
|
|
// rmp and da magnitudes are 1.0
|
2016-04-16 11:58:23 +00:00
|
|
|
startAngle = -std::max(acos(rmp.Dot(da)), extAngle);
|
|
|
|
addAngle = -startAngle;
|
|
|
|
|
|
|
|
if(arrowVisible) {
|
|
|
|
addAngle += extAngle;
|
|
|
|
arrowRev = true;
|
|
|
|
}
|
2016-04-15 11:57:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Vector prev;
|
|
|
|
int n = 30;
|
|
|
|
for(int i = 0; i <= n; i++) {
|
2016-04-16 11:58:23 +00:00
|
|
|
double theta = startAngle + (i*(thetaf + addAngle))/n;
|
|
|
|
Vector p = da.ScaledBy(r*cos(theta)).Plus(
|
|
|
|
dna.ScaledBy(r*sin(theta))).Plus(pi);
|
2016-04-15 11:57:44 +00:00
|
|
|
if(i > 0) {
|
|
|
|
if(trim) {
|
2016-05-25 12:08:19 +00:00
|
|
|
DoLineTrimmedAgainstBox(*ref, prev, p, /*extend=*/false, gr, gu, swidth, sheight);
|
2016-04-15 11:57:44 +00:00
|
|
|
} else {
|
|
|
|
LineDrawOrGetDistance(prev, p);
|
|
|
|
}
|
2016-04-13 02:45:52 +00:00
|
|
|
}
|
2008-07-20 12:24:43 +00:00
|
|
|
prev = p;
|
|
|
|
}
|
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
DoLineExtend(a0, a1, apa, 5.0 * px);
|
|
|
|
DoLineExtend(b0, b1, apb, 5.0 * px);
|
|
|
|
|
|
|
|
// Draw arrows only when we have enough space.
|
2016-04-16 11:58:23 +00:00
|
|
|
if(arrowVisible) {
|
2016-04-11 14:21:41 +00:00
|
|
|
double angleCorr = arrowW / (2.0 * r);
|
2016-04-16 11:58:23 +00:00
|
|
|
if(arrowRev) {
|
|
|
|
dna = dna.ScaledBy(-1.0);
|
|
|
|
angleCorr = -angleCorr;
|
|
|
|
}
|
2016-04-11 14:21:41 +00:00
|
|
|
DoArrow(apa, dna, norm, arrowW, arrowA, angleCorr);
|
|
|
|
DoArrow(apb, dna, norm, arrowW, arrowA, thetaf + PI - angleCorr);
|
|
|
|
}
|
2008-07-20 12:24:43 +00:00
|
|
|
} else {
|
|
|
|
// The lines are skew; no wonderful way to illustrate that.
|
|
|
|
*ref = a0.Plus(b0);
|
|
|
|
*ref = (*ref).ScaledBy(0.5).Plus(disp.offset);
|
2009-07-03 20:55:57 +00:00
|
|
|
gu = gu.WithMagnitude(1);
|
2009-09-24 15:52:48 +00:00
|
|
|
Vector trans =
|
2016-04-12 13:38:09 +00:00
|
|
|
(*ref).Plus(gu.ScaledBy(-1.5*ssglStrCapHeight(Style::DefaultTextHeight())));
|
2016-03-02 17:15:28 +00:00
|
|
|
ssglWriteTextRefCenter("angle between skew lines", Style::DefaultTextHeight(),
|
2016-05-21 05:18:00 +00:00
|
|
|
trans, gr.WithMagnitude(px), gu.WithMagnitude(px), LineCallback, (void *)this);
|
2008-07-20 12:24:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-24 13:55:36 +00:00
|
|
|
bool Constraint::IsVisible() const {
|
|
|
|
if(!SS.GW.showConstraints) return false;
|
2009-04-19 05:53:16 +00:00
|
|
|
Group *g = SK.GetGroup(group);
|
2008-04-28 07:18:39 +00:00
|
|
|
// If the group is hidden, then the constraints are hidden and not
|
|
|
|
// able to be selected.
|
2016-03-24 13:55:36 +00:00
|
|
|
if(!(g->visible)) return false;
|
2009-09-29 11:35:19 +00:00
|
|
|
// And likewise if the group is not the active group; except for comments
|
|
|
|
// with an assigned style.
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(g->h.v != SS.GW.activeGroup.v && !(type == Type::COMMENT && disp.style.v)) {
|
2016-03-24 13:55:36 +00:00
|
|
|
return false;
|
2009-09-29 11:35:19 +00:00
|
|
|
}
|
|
|
|
if(disp.style.v) {
|
|
|
|
Style *s = Style::Get(disp.style);
|
2016-03-24 13:55:36 +00:00
|
|
|
if(!s->visible) return false;
|
2009-09-29 11:35:19 +00:00
|
|
|
}
|
2016-03-24 13:55:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
2008-04-21 08:16:38 +00:00
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
bool Constraint::DoLineExtend(Vector p0, Vector p1, Vector pt, double salient) {
|
|
|
|
Vector dir = p1.Minus(p0);
|
|
|
|
double k = dir.Dot(pt.Minus(p0)) / dir.Dot(dir);
|
|
|
|
Vector ptOnLine = p0.Plus(dir.ScaledBy(k));
|
|
|
|
|
|
|
|
// Draw projection line.
|
|
|
|
LineDrawOrGetDistance(pt, ptOnLine);
|
|
|
|
|
|
|
|
// Calculate salient direction.
|
|
|
|
Vector sd = dir.WithMagnitude(1.0).ScaledBy(salient);
|
|
|
|
|
|
|
|
Vector from;
|
|
|
|
Vector to;
|
|
|
|
|
|
|
|
if(k < 0.0) {
|
|
|
|
from = p0;
|
|
|
|
to = ptOnLine.Minus(sd);
|
|
|
|
} else if(k > 1.0) {
|
|
|
|
from = p1;
|
|
|
|
to = ptOnLine.Plus(sd);
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw extension line.
|
|
|
|
LineDrawOrGetDistance(from, to);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
|
2016-03-24 13:55:36 +00:00
|
|
|
if(!IsVisible()) return;
|
2016-04-11 14:21:41 +00:00
|
|
|
|
2008-04-28 09:40:02 +00:00
|
|
|
// Unit vectors that describe our current view of the scene. One pixel
|
|
|
|
// long, not one actual unit.
|
|
|
|
Vector gr = SS.GW.projRight.ScaledBy(1/SS.GW.scale);
|
|
|
|
Vector gu = SS.GW.projUp.ScaledBy(1/SS.GW.scale);
|
|
|
|
Vector gn = (gr.Cross(gu)).WithMagnitude(1/SS.GW.scale);
|
2008-04-14 10:28:32 +00:00
|
|
|
|
|
|
|
switch(type) {
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PT_PT_DISTANCE: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector ap = SK.GetEntity(ptA)->PointGetNum();
|
|
|
|
Vector bp = SK.GetEntity(ptB)->PointGetNum();
|
2008-04-14 10:28:32 +00:00
|
|
|
|
2008-05-08 07:30:30 +00:00
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
DoProjectedPoint(&ap);
|
|
|
|
DoProjectedPoint(&bp);
|
|
|
|
}
|
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = ref;
|
2008-04-14 10:28:32 +00:00
|
|
|
|
2016-05-25 12:08:19 +00:00
|
|
|
DoLineWithArrows(ref, ap, bp, /*onlyOneExt=*/false);
|
2008-05-07 08:19:37 +00:00
|
|
|
DoLabel(ref, labelPos, gr, gu);
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-07 08:19:37 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PROJ_PT_DISTANCE: {
|
2010-01-27 18:15:06 +00:00
|
|
|
Vector ap = SK.GetEntity(ptA)->PointGetNum(),
|
|
|
|
bp = SK.GetEntity(ptB)->PointGetNum(),
|
|
|
|
dp = (bp.Minus(ap)),
|
|
|
|
pp = SK.GetEntity(entityA)->VectorGetNum();
|
|
|
|
|
|
|
|
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = ref;
|
2010-01-27 18:15:06 +00:00
|
|
|
|
|
|
|
pp = pp.WithMagnitude(1);
|
|
|
|
double d = dp.Dot(pp);
|
|
|
|
Vector bpp = ap.Plus(pp.ScaledBy(d));
|
|
|
|
StippledLine(ap, bpp);
|
|
|
|
StippledLine(bp, bpp);
|
|
|
|
|
2016-05-25 12:08:19 +00:00
|
|
|
DoLineWithArrows(ref, ap, bpp, /*onlyOneExt=*/false);
|
2010-01-27 18:15:06 +00:00
|
|
|
DoLabel(ref, labelPos, gr, gu);
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2010-01-27 18:15:06 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PT_FACE_DISTANCE:
|
|
|
|
case Type::PT_PLANE_DISTANCE: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector pt = SK.GetEntity(ptA)->PointGetNum();
|
|
|
|
Entity *enta = SK.GetEntity(entityA);
|
2008-06-06 08:46:55 +00:00
|
|
|
Vector n, p;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::PT_PLANE_DISTANCE) {
|
2008-06-06 08:46:55 +00:00
|
|
|
n = enta->Normal()->NormalN();
|
|
|
|
p = enta->WorkplaneGetOffset();
|
|
|
|
} else {
|
|
|
|
n = enta->FaceGetNormalNum();
|
|
|
|
p = enta->FaceGetPointNum();
|
|
|
|
}
|
|
|
|
|
2008-05-08 07:30:30 +00:00
|
|
|
double d = (p.Minus(pt)).Dot(n);
|
|
|
|
Vector closest = pt.Plus(n.WithMagnitude(d));
|
|
|
|
|
|
|
|
Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(disp.offset);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = ref;
|
2009-09-03 08:13:09 +00:00
|
|
|
|
|
|
|
if(!pt.Equals(closest)) {
|
2016-05-25 12:08:19 +00:00
|
|
|
DoLineWithArrows(ref, pt, closest, /*onlyOneExt=*/true);
|
2009-09-03 08:13:09 +00:00
|
|
|
}
|
|
|
|
|
2008-05-08 07:30:30 +00:00
|
|
|
DoLabel(ref, labelPos, gr, gu);
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-08 07:30:30 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PT_LINE_DISTANCE: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector pt = SK.GetEntity(ptA)->PointGetNum();
|
|
|
|
Entity *line = SK.GetEntity(entityA);
|
|
|
|
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
|
|
|
|
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
|
2009-09-03 08:13:09 +00:00
|
|
|
Vector dl = lB.Minus(lA);
|
2008-05-08 07:30:30 +00:00
|
|
|
|
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
lA = lA.ProjectInto(workplane);
|
|
|
|
lB = lB.ProjectInto(workplane);
|
|
|
|
DoProjectedPoint(&pt);
|
|
|
|
}
|
|
|
|
|
2008-06-14 11:16:14 +00:00
|
|
|
// Find the closest point on the line
|
2009-09-03 08:13:09 +00:00
|
|
|
Vector closest = pt.ClosestPointOnLine(lA, dl);
|
2008-06-14 11:16:14 +00:00
|
|
|
|
2008-05-08 07:30:30 +00:00
|
|
|
Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(disp.offset);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = ref;
|
2008-05-08 07:30:30 +00:00
|
|
|
DoLabel(ref, labelPos, gr, gu);
|
2008-05-08 08:12:23 +00:00
|
|
|
|
2009-09-03 08:13:09 +00:00
|
|
|
if(!pt.Equals(closest)) {
|
2016-05-25 12:08:19 +00:00
|
|
|
DoLineWithArrows(ref, pt, closest, /*onlyOneExt=*/true);
|
2016-03-02 17:15:28 +00:00
|
|
|
|
2016-01-08 05:20:37 +00:00
|
|
|
// Extensions to line
|
|
|
|
double pixels = 1.0 / SS.GW.scale;
|
|
|
|
Vector refClosest = ref.ClosestPointOnLine(lA, dl);
|
|
|
|
double ddl = dl.Dot(dl);
|
|
|
|
if(fabs(ddl) > LENGTH_EPS * LENGTH_EPS) {
|
|
|
|
double t = refClosest.Minus(lA).Dot(dl) / ddl;
|
|
|
|
if(t < 0.0) {
|
|
|
|
LineDrawOrGetDistance(refClosest.Minus(dl.WithMagnitude(10.0 * pixels)), lA);
|
|
|
|
} else if(t > 1.0) {
|
|
|
|
LineDrawOrGetDistance(refClosest.Plus(dl.WithMagnitude(10.0 * pixels)), lB);
|
|
|
|
}
|
|
|
|
}
|
2009-09-03 08:13:09 +00:00
|
|
|
}
|
|
|
|
|
2008-05-08 08:12:23 +00:00
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
// Draw the projection marker from the closest point on the
|
|
|
|
// projected line to the projected point on the real line.
|
2008-06-14 11:16:14 +00:00
|
|
|
Vector lAB = (lA.Minus(lB));
|
2008-05-08 08:12:23 +00:00
|
|
|
double t = (lA.Minus(closest)).DivPivoting(lAB);
|
|
|
|
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
|
|
|
|
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
|
2008-05-08 08:12:23 +00:00
|
|
|
|
|
|
|
Vector c2 = (lA.ScaledBy(1-t)).Plus(lB.ScaledBy(t));
|
|
|
|
DoProjectedPoint(&c2);
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-08 07:30:30 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::DIAMETER: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *circle = SK.GetEntity(entityA);
|
|
|
|
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
|
2009-09-03 08:13:09 +00:00
|
|
|
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
|
|
|
|
Vector n = q.RotationN().WithMagnitude(1);
|
2008-05-12 10:01:44 +00:00
|
|
|
double r = circle->CircleGetRadiusNum();
|
2008-05-07 08:19:37 +00:00
|
|
|
|
2009-09-03 08:13:09 +00:00
|
|
|
Vector ref = center.Plus(disp.offset);
|
|
|
|
// Force the label into the same plane as the circle.
|
|
|
|
ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = ref;
|
2008-05-07 08:19:37 +00:00
|
|
|
|
|
|
|
Vector mark = ref.Minus(center);
|
|
|
|
mark = mark.WithMagnitude(mark.Magnitude()-r);
|
2009-09-03 08:13:09 +00:00
|
|
|
DoLineTrimmedAgainstBox(ref, ref, ref.Minus(mark));
|
2008-04-14 10:28:32 +00:00
|
|
|
|
2010-05-23 06:21:42 +00:00
|
|
|
Vector topLeft;
|
|
|
|
DoLabel(ref, &topLeft, gr, gu);
|
|
|
|
if(labelPos) *labelPos = topLeft;
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-14 10:28:32 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::POINTS_COINCIDENT: {
|
2008-04-22 10:53:42 +00:00
|
|
|
if(!dogd.drawing) {
|
|
|
|
for(int i = 0; i < 2; i++) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[i] = p;
|
2008-04-22 10:53:42 +00:00
|
|
|
Point2d pp = SS.GW.ProjectPoint(p);
|
|
|
|
// The point is selected within a radius of 7, from the
|
|
|
|
// same center; so if the point is visible, then this
|
|
|
|
// constraint cannot be selected. But that's okay.
|
|
|
|
dogd.dmin = min(dogd.dmin, pp.DistanceTo(dogd.mp) - 3);
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-22 10:53:42 +00:00
|
|
|
}
|
|
|
|
|
2015-03-26 00:34:28 +00:00
|
|
|
if(dogd.drawing) {
|
|
|
|
// Let's adjust the color of this constraint to have the same
|
|
|
|
// rough luma as the point color, so that the constraint does not
|
|
|
|
// stand out in an ugly way.
|
2015-07-10 11:54:39 +00:00
|
|
|
RgbaColor cd = Style::Color(Style::DATUM),
|
2015-03-26 00:34:28 +00:00
|
|
|
cc = Style::Color(Style::CONSTRAINT);
|
|
|
|
// convert from 8-bit color to a vector
|
|
|
|
Vector vd = Vector::From(cd.redF(), cd.greenF(), cd.blueF()),
|
|
|
|
vc = Vector::From(cc.redF(), cc.greenF(), cc.blueF());
|
|
|
|
// and scale the constraint color to have the same magnitude as
|
|
|
|
// the datum color, maybe a bit dimmer
|
|
|
|
vc = vc.WithMagnitude(vd.Magnitude()*0.9);
|
|
|
|
// and set the color to that.
|
|
|
|
ssglColorRGB(RGBf(vc.x, vc.y, vc.z));
|
|
|
|
|
|
|
|
for(int a = 0; a < 2; a++) {
|
|
|
|
Vector r = SS.GW.projRight.ScaledBy((a+1)/SS.GW.scale);
|
|
|
|
Vector d = SS.GW.projUp.ScaledBy((2-a)/SS.GW.scale);
|
|
|
|
for(int i = 0; i < 2; i++) {
|
|
|
|
Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum();
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
ssglVertex3v(p.Plus (r).Plus (d));
|
|
|
|
ssglVertex3v(p.Plus (r).Minus(d));
|
|
|
|
ssglVertex3v(p.Minus(r).Minus(d));
|
|
|
|
ssglVertex3v(p.Minus(r).Plus (d));
|
|
|
|
glEnd();
|
|
|
|
}
|
2008-04-22 10:53:42 +00:00
|
|
|
|
2015-03-26 00:34:28 +00:00
|
|
|
}
|
2008-04-21 08:16:38 +00:00
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-21 08:16:38 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PT_ON_CIRCLE:
|
|
|
|
case Type::PT_ON_LINE:
|
|
|
|
case Type::PT_ON_FACE:
|
|
|
|
case Type::PT_IN_PLANE: {
|
2008-06-02 03:31:37 +00:00
|
|
|
double s = 8/SS.GW.scale;
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector p = SK.GetEntity(ptA)->PointGetNum();
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = p;
|
2008-06-02 03:31:37 +00:00
|
|
|
Vector r, d;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::PT_ON_FACE) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector n = SK.GetEntity(entityA)->FaceGetNormalNum();
|
2008-06-02 03:31:37 +00:00
|
|
|
r = n.Normal(0);
|
|
|
|
d = n.Normal(1);
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
} else if(type == Type::PT_IN_PLANE) {
|
2009-04-20 07:30:09 +00:00
|
|
|
EntityBase *n = SK.GetEntity(entityA)->Normal();
|
2008-06-02 03:31:37 +00:00
|
|
|
r = n->NormalU();
|
|
|
|
d = n->NormalV();
|
|
|
|
} else {
|
|
|
|
r = gr;
|
|
|
|
d = gu;
|
|
|
|
s *= (6.0/8); // draw these a little smaller
|
|
|
|
}
|
|
|
|
r = r.WithMagnitude(s); d = d.WithMagnitude(s);
|
2008-04-21 08:16:38 +00:00
|
|
|
LineDrawOrGetDistance(p.Plus (r).Plus (d), p.Plus (r).Minus(d));
|
|
|
|
LineDrawOrGetDistance(p.Plus (r).Minus(d), p.Minus(r).Minus(d));
|
|
|
|
LineDrawOrGetDistance(p.Minus(r).Minus(d), p.Minus(r).Plus (d));
|
|
|
|
LineDrawOrGetDistance(p.Minus(r).Plus (d), p.Plus (r).Plus (d));
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-21 08:16:38 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::WHERE_DRAGGED: {
|
2016-05-24 06:40:41 +00:00
|
|
|
Vector p = SK.GetEntity(ptA)->PointGetNum();
|
|
|
|
if(refps) refps[0] = refps[1] = p;
|
|
|
|
Vector u = p.Plus(gu.WithMagnitude(8/SS.GW.scale)).Plus(
|
2010-05-04 05:11:52 +00:00
|
|
|
gr.WithMagnitude(8/SS.GW.scale)),
|
|
|
|
uu = u.Minus(gu.WithMagnitude(5/SS.GW.scale)),
|
|
|
|
ur = u.Minus(gr.WithMagnitude(5/SS.GW.scale));
|
|
|
|
// Draw four little crop marks, uniformly spaced (by ninety
|
|
|
|
// degree rotations) around the point.
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < 4; i++) {
|
|
|
|
LineDrawOrGetDistance(u, uu);
|
|
|
|
LineDrawOrGetDistance(u, ur);
|
|
|
|
u = u.RotatedAbout(p, gn, PI/2);
|
|
|
|
ur = ur.RotatedAbout(p, gn, PI/2);
|
|
|
|
uu = uu.RotatedAbout(p, gn, PI/2);
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2010-05-04 05:11:52 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::SAME_ORIENTATION: {
|
2008-05-09 05:33:23 +00:00
|
|
|
for(int i = 0; i < 2; i++) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
|
2008-05-09 05:33:23 +00:00
|
|
|
Quaternion q = e->NormalGetNum();
|
|
|
|
Vector n = q.RotationN().WithMagnitude(25/SS.GW.scale);
|
|
|
|
Vector u = q.RotationU().WithMagnitude(6/SS.GW.scale);
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector p = SK.GetEntity(e->point[0])->PointGetNum();
|
2008-05-09 05:33:23 +00:00
|
|
|
p = p.Plus(n.WithMagnitude(10/SS.GW.scale));
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[i] = p;
|
2008-05-09 05:33:23 +00:00
|
|
|
|
|
|
|
LineDrawOrGetDistance(p.Plus(u), p.Minus(u).Plus(n));
|
|
|
|
LineDrawOrGetDistance(p.Minus(u), p.Plus(u).Plus(n));
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-09 05:33:23 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::EQUAL_ANGLE: {
|
2008-07-20 12:24:43 +00:00
|
|
|
Vector ref;
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *a = SK.GetEntity(entityA);
|
|
|
|
Entity *b = SK.GetEntity(entityB);
|
|
|
|
Entity *c = SK.GetEntity(entityC);
|
|
|
|
Entity *d = SK.GetEntity(entityD);
|
2008-07-20 12:24:43 +00:00
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
Vector a0 = a->VectorGetStartPoint();
|
|
|
|
Vector b0 = b->VectorGetStartPoint();
|
|
|
|
Vector c0 = c->VectorGetStartPoint();
|
|
|
|
Vector d0 = d->VectorGetStartPoint();
|
2008-05-17 11:15:14 +00:00
|
|
|
Vector da = a->VectorGetNum();
|
|
|
|
Vector db = b->VectorGetNum();
|
2008-07-20 12:24:43 +00:00
|
|
|
Vector dc = c->VectorGetNum();
|
|
|
|
Vector dd = d->VectorGetNum();
|
2008-05-17 11:15:14 +00:00
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
if(other) {
|
|
|
|
a0 = a0.Plus(da);
|
|
|
|
da = da.ScaledBy(-1);
|
|
|
|
}
|
2008-05-17 11:15:14 +00:00
|
|
|
|
2015-03-29 00:30:52 +00:00
|
|
|
DoArcForAngle(a0, da, b0, db,
|
2016-04-13 02:45:52 +00:00
|
|
|
da.WithMagnitude(40/SS.GW.scale), &ref, /*trim=*/false);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = ref;
|
2015-03-29 00:30:52 +00:00
|
|
|
DoArcForAngle(c0, dc, d0, dd,
|
2016-04-13 02:45:52 +00:00
|
|
|
dc.WithMagnitude(40/SS.GW.scale), &ref, /*trim=*/false);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[1] = ref;
|
2008-05-17 11:15:14 +00:00
|
|
|
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-07-20 12:24:43 +00:00
|
|
|
}
|
2008-05-17 11:15:14 +00:00
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::ANGLE: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *a = SK.GetEntity(entityA);
|
|
|
|
Entity *b = SK.GetEntity(entityB);
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2016-04-11 14:21:41 +00:00
|
|
|
Vector a0 = a->VectorGetStartPoint();
|
|
|
|
Vector b0 = b->VectorGetStartPoint();
|
2008-07-20 12:24:43 +00:00
|
|
|
Vector da = a->VectorGetNum();
|
|
|
|
Vector db = b->VectorGetNum();
|
2016-04-11 14:21:41 +00:00
|
|
|
if(other) {
|
|
|
|
a0 = a0.Plus(da);
|
|
|
|
da = da.ScaledBy(-1);
|
|
|
|
}
|
2008-07-20 12:24:43 +00:00
|
|
|
|
|
|
|
Vector ref;
|
2016-04-13 02:45:52 +00:00
|
|
|
DoArcForAngle(a0, da, b0, db, disp.offset, &ref, /*trim=*/true);
|
2008-05-17 11:15:14 +00:00
|
|
|
DoLabel(ref, labelPos, gr, gu);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = ref;
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-07-02 09:21:29 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PERPENDICULAR: {
|
2013-08-26 19:36:00 +00:00
|
|
|
Vector u = Vector::From(0, 0, 0), v = Vector::From(0, 0, 0);
|
2008-07-02 09:21:29 +00:00
|
|
|
Vector rn, ru;
|
|
|
|
if(workplane.v == Entity::FREE_IN_3D.v) {
|
|
|
|
rn = gn;
|
|
|
|
ru = gu;
|
|
|
|
} else {
|
2009-04-20 07:30:09 +00:00
|
|
|
EntityBase *normal = SK.GetEntity(workplane)->Normal();
|
2008-07-02 09:21:29 +00:00
|
|
|
rn = normal->NormalN();
|
|
|
|
ru = normal->NormalV(); // ru meaning r_up, not u/v
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int i = 0; i < 2; i++) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
|
2008-07-02 09:21:29 +00:00
|
|
|
|
|
|
|
if(i == 0) {
|
|
|
|
// Calculate orientation of perpendicular sign only
|
|
|
|
// once, so that it's the same both times it's drawn
|
|
|
|
u = e->VectorGetNum();
|
|
|
|
u = u.WithMagnitude(16/SS.GW.scale);
|
|
|
|
v = (rn.Cross(u)).WithMagnitude(16/SS.GW.scale);
|
2009-11-29 02:42:50 +00:00
|
|
|
// a bit of bias to stop it from flickering between the
|
|
|
|
// two possibilities
|
|
|
|
if(fabs(u.Dot(ru)) < fabs(v.Dot(ru)) + LENGTH_EPS) {
|
2015-03-27 15:43:28 +00:00
|
|
|
swap(u, v);
|
2008-07-02 09:21:29 +00:00
|
|
|
}
|
|
|
|
if(u.Dot(ru) < 0) u = u.ScaledBy(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector p = e->VectorGetRefPoint();
|
|
|
|
Vector s = p.Plus(u).Plus(v);
|
|
|
|
LineDrawOrGetDistance(s, s.Plus(v));
|
|
|
|
Vector m = s.Plus(v.ScaledBy(0.5));
|
|
|
|
LineDrawOrGetDistance(m, m.Plus(u));
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[i] = m;
|
2008-07-02 09:21:29 +00:00
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-07-13 12:44:05 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::CURVE_CURVE_TANGENT:
|
|
|
|
case Type::CUBIC_LINE_TANGENT:
|
|
|
|
case Type::ARC_LINE_TANGENT: {
|
2008-07-13 12:44:05 +00:00
|
|
|
Vector textAt, u, v;
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::ARC_LINE_TANGENT) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *arc = SK.GetEntity(entityA);
|
|
|
|
Entity *norm = SK.GetEntity(arc->normal);
|
|
|
|
Vector c = SK.GetEntity(arc->point[0])->PointGetNum();
|
2015-03-29 00:30:52 +00:00
|
|
|
Vector p =
|
2009-04-19 05:53:16 +00:00
|
|
|
SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum();
|
2008-07-13 12:44:05 +00:00
|
|
|
Vector r = p.Minus(c);
|
|
|
|
textAt = p.Plus(r.WithMagnitude(14/SS.GW.scale));
|
|
|
|
u = norm->NormalU();
|
|
|
|
v = norm->NormalV();
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
} else if(type == Type::CUBIC_LINE_TANGENT) {
|
2008-07-13 12:44:05 +00:00
|
|
|
Vector n;
|
|
|
|
if(workplane.v == Entity::FREE_IN_3D.v) {
|
|
|
|
u = gr;
|
|
|
|
v = gu;
|
|
|
|
n = gn;
|
|
|
|
} else {
|
2009-04-20 07:30:09 +00:00
|
|
|
EntityBase *wn = SK.GetEntity(workplane)->Normal();
|
2008-07-13 12:44:05 +00:00
|
|
|
u = wn->NormalU();
|
|
|
|
v = wn->NormalV();
|
|
|
|
n = wn->NormalN();
|
|
|
|
}
|
|
|
|
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *cubic = SK.GetEntity(entityA);
|
2009-10-21 04:46:01 +00:00
|
|
|
Vector p = other ? cubic->CubicGetFinishNum() :
|
2015-03-29 00:30:52 +00:00
|
|
|
cubic->CubicGetStartNum();
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector dir = SK.GetEntity(entityB)->VectorGetNum();
|
2008-07-13 12:44:05 +00:00
|
|
|
Vector out = n.Cross(dir);
|
|
|
|
textAt = p.Plus(out.WithMagnitude(14/SS.GW.scale));
|
2010-05-10 04:14:06 +00:00
|
|
|
} else {
|
|
|
|
Vector n, dir;
|
|
|
|
EntityBase *wn = SK.GetEntity(workplane)->Normal();
|
|
|
|
u = wn->NormalU();
|
|
|
|
v = wn->NormalV();
|
|
|
|
n = wn->NormalN();
|
|
|
|
EntityBase *eA = SK.GetEntity(entityA);
|
|
|
|
// Big pain; we have to get a vector tangent to the curve
|
|
|
|
// at the shared point, which could be from either a cubic
|
|
|
|
// or an arc.
|
|
|
|
if(other) {
|
|
|
|
textAt = eA->EndpointFinish();
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(eA->type == Entity::Type::CUBIC) {
|
2010-05-10 04:14:06 +00:00
|
|
|
dir = eA->CubicGetFinishTangentNum();
|
|
|
|
} else {
|
|
|
|
dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus(
|
|
|
|
SK.GetEntity(eA->point[2])->PointGetNum());
|
|
|
|
dir = n.Cross(dir);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
textAt = eA->EndpointStart();
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(eA->type == Entity::Type::CUBIC) {
|
2010-05-10 04:14:06 +00:00
|
|
|
dir = eA->CubicGetStartTangentNum();
|
|
|
|
} else {
|
|
|
|
dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus(
|
|
|
|
SK.GetEntity(eA->point[1])->PointGetNum());
|
|
|
|
dir = n.Cross(dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dir = n.Cross(dir);
|
|
|
|
textAt = textAt.Plus(dir.WithMagnitude(14/SS.GW.scale));
|
2008-07-13 12:44:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(dogd.drawing) {
|
2016-03-02 17:15:28 +00:00
|
|
|
ssglWriteTextRefCenter("T", Style::DefaultTextHeight(),
|
2016-05-21 05:18:00 +00:00
|
|
|
textAt, u, v, LineCallback, (void *)this);
|
2008-07-13 12:44:05 +00:00
|
|
|
} else {
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = textAt;
|
|
|
|
Point2d ref = SS.GW.ProjectPoint(textAt);
|
2008-07-13 12:44:05 +00:00
|
|
|
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-17 11:15:14 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::PARALLEL: {
|
2008-05-09 05:33:23 +00:00
|
|
|
for(int i = 0; i < 2; i++) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
|
2008-05-11 10:40:37 +00:00
|
|
|
Vector n = e->VectorGetNum();
|
2008-05-09 05:33:23 +00:00
|
|
|
n = n.WithMagnitude(25/SS.GW.scale);
|
|
|
|
Vector u = (gn.Cross(n)).WithMagnitude(4/SS.GW.scale);
|
|
|
|
Vector p = e->VectorGetRefPoint();
|
|
|
|
|
|
|
|
LineDrawOrGetDistance(p.Plus(u), p.Plus(u).Plus(n));
|
|
|
|
LineDrawOrGetDistance(p.Minus(u), p.Minus(u).Plus(n));
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[i] = p.Plus(n.ScaledBy(0.5));
|
2008-05-09 05:33:23 +00:00
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-09 05:33:23 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::EQUAL_RADIUS: {
|
2008-05-12 10:01:44 +00:00
|
|
|
for(int i = 0; i < 2; i++) {
|
2016-05-24 06:40:41 +00:00
|
|
|
Vector ref;
|
|
|
|
DoEqualRadiusTicks(i == 0 ? entityA : entityB, &ref);
|
|
|
|
if(refps) refps[i] = ref;
|
2008-05-12 10:01:44 +00:00
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-05-12 10:01:44 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::EQUAL_LINE_ARC_LEN: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *line = SK.GetEntity(entityA);
|
2016-05-24 06:40:41 +00:00
|
|
|
Vector refa, refb;
|
2009-01-08 17:22:59 +00:00
|
|
|
DoEqualLenTicks(
|
2009-04-19 05:53:16 +00:00
|
|
|
SK.GetEntity(line->point[0])->PointGetNum(),
|
|
|
|
SK.GetEntity(line->point[1])->PointGetNum(),
|
2016-05-24 06:40:41 +00:00
|
|
|
gn, &refa);
|
|
|
|
DoEqualRadiusTicks(entityB, &refb); // FIXME
|
|
|
|
if(refps) {
|
|
|
|
refps[0] = refa;
|
|
|
|
refps[1] = refb;
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2009-01-08 17:22:59 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::LENGTH_RATIO:
|
|
|
|
case Type::LENGTH_DIFFERENCE:
|
|
|
|
case Type::EQUAL_LENGTH_LINES: {
|
2013-08-26 19:36:00 +00:00
|
|
|
Vector a, b = Vector::From(0, 0, 0);
|
2008-04-22 05:00:49 +00:00
|
|
|
for(int i = 0; i < 2; i++) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *e = SK.GetEntity(i == 0 ? entityA : entityB);
|
|
|
|
a = SK.GetEntity(e->point[0])->PointGetNum();
|
|
|
|
b = SK.GetEntity(e->point[1])->PointGetNum();
|
2008-06-14 11:16:14 +00:00
|
|
|
|
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
DoProjectedPoint(&a);
|
|
|
|
DoProjectedPoint(&b);
|
|
|
|
}
|
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
Vector ref;
|
|
|
|
DoEqualLenTicks(a, b, gn, &ref);
|
|
|
|
if(refps) refps[i] = ref;
|
2008-04-22 05:00:49 +00:00
|
|
|
}
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if((type == Type::LENGTH_RATIO) || (type == Type::LENGTH_DIFFERENCE)) {
|
2008-05-11 10:40:37 +00:00
|
|
|
Vector ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset);
|
|
|
|
DoLabel(ref, labelPos, gr, gu);
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-22 05:00:49 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::EQ_LEN_PT_LINE_D: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *forLen = SK.GetEntity(entityA);
|
|
|
|
Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(),
|
|
|
|
b = SK.GetEntity(forLen->point[1])->PointGetNum();
|
2008-06-14 11:16:14 +00:00
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
DoProjectedPoint(&a);
|
|
|
|
DoProjectedPoint(&b);
|
|
|
|
}
|
2016-05-24 06:40:41 +00:00
|
|
|
Vector refa;
|
|
|
|
DoEqualLenTicks(a, b, gn, &refa);
|
|
|
|
if(refps) refps[0] = refa;
|
2008-06-14 11:16:14 +00:00
|
|
|
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *ln = SK.GetEntity(entityB);
|
|
|
|
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
|
|
|
|
lb = SK.GetEntity(ln->point[1])->PointGetNum();
|
|
|
|
Vector pt = SK.GetEntity(ptA)->PointGetNum();
|
2008-06-14 11:16:14 +00:00
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
DoProjectedPoint(&pt);
|
|
|
|
la = la.ProjectInto(workplane);
|
|
|
|
lb = lb.ProjectInto(workplane);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la));
|
|
|
|
LineDrawOrGetDistance(pt, closest);
|
2016-05-24 06:40:41 +00:00
|
|
|
Vector refb;
|
|
|
|
DoEqualLenTicks(pt, closest, gn, &refb);
|
|
|
|
if(refps) refps[1] = refb;
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-06-14 11:16:14 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::EQ_PT_LN_DISTANCES: {
|
2008-06-14 11:16:14 +00:00
|
|
|
for(int i = 0; i < 2; i++) {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB);
|
|
|
|
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
|
|
|
|
lb = SK.GetEntity(ln->point[1])->PointGetNum();
|
|
|
|
Entity *pte = SK.GetEntity(i == 0 ? ptA : ptB);
|
2008-06-14 11:16:14 +00:00
|
|
|
Vector pt = pte->PointGetNum();
|
|
|
|
|
|
|
|
if(workplane.v != Entity::FREE_IN_3D.v) {
|
|
|
|
DoProjectedPoint(&pt);
|
|
|
|
la = la.ProjectInto(workplane);
|
|
|
|
lb = lb.ProjectInto(workplane);
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la));
|
|
|
|
LineDrawOrGetDistance(pt, closest);
|
2016-05-24 06:40:41 +00:00
|
|
|
|
|
|
|
Vector ref;
|
|
|
|
DoEqualLenTicks(pt, closest, gn, &ref);
|
|
|
|
if(refps) refps[i] = ref;
|
2008-06-14 11:16:14 +00:00
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-06-14 11:16:14 +00:00
|
|
|
}
|
|
|
|
|
2008-05-13 10:38:21 +00:00
|
|
|
{
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::SYMMETRIC:
|
2013-10-19 05:36:45 +00:00
|
|
|
Vector n;
|
2009-04-19 05:53:16 +00:00
|
|
|
n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::SYMMETRIC_HORIZ:
|
2009-04-19 05:53:16 +00:00
|
|
|
n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::SYMMETRIC_VERT:
|
2009-04-19 05:53:16 +00:00
|
|
|
n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s;
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::SYMMETRIC_LINE: {
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *ln = SK.GetEntity(entityA);
|
|
|
|
Vector la = SK.GetEntity(ln->point[0])->PointGetNum(),
|
|
|
|
lb = SK.GetEntity(ln->point[1])->PointGetNum();
|
2008-07-02 06:59:49 +00:00
|
|
|
la = la.ProjectInto(workplane);
|
|
|
|
lb = lb.ProjectInto(workplane);
|
|
|
|
n = lb.Minus(la);
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector nw = SK.GetEntity(workplane)->Normal()->NormalN();
|
2008-07-02 06:59:49 +00:00
|
|
|
n = n.RotatedAbout(nw, PI/2);
|
|
|
|
goto s;
|
|
|
|
}
|
2008-05-13 10:38:21 +00:00
|
|
|
s:
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector a = SK.GetEntity(ptA)->PointGetNum();
|
|
|
|
Vector b = SK.GetEntity(ptB)->PointGetNum();
|
2008-07-02 06:59:49 +00:00
|
|
|
|
2008-04-30 08:14:32 +00:00
|
|
|
for(int i = 0; i < 2; i++) {
|
|
|
|
Vector tail = (i == 0) ? a : b;
|
|
|
|
Vector d = (i == 0) ? b : a;
|
|
|
|
d = d.Minus(tail);
|
|
|
|
// Project the direction in which the arrow is drawn normal
|
|
|
|
// to the symmetry plane; for projected symmetry constraints,
|
|
|
|
// they might not be in the same direction, even when the
|
|
|
|
// constraint is fully solved.
|
|
|
|
d = n.ScaledBy(d.Dot(n));
|
|
|
|
d = d.WithMagnitude(20/SS.GW.scale);
|
|
|
|
Vector tip = tail.Plus(d);
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[i] = tip;
|
2008-04-30 08:14:32 +00:00
|
|
|
|
|
|
|
LineDrawOrGetDistance(tail, tip);
|
|
|
|
d = d.WithMagnitude(9/SS.GW.scale);
|
|
|
|
LineDrawOrGetDistance(tip, tip.Minus(d.RotatedAbout(gn, 0.6)));
|
|
|
|
LineDrawOrGetDistance(tip, tip.Minus(d.RotatedAbout(gn, -0.6)));
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-30 08:14:32 +00:00
|
|
|
}
|
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::AT_MIDPOINT:
|
|
|
|
case Type::HORIZONTAL:
|
|
|
|
case Type::VERTICAL:
|
2008-04-23 07:29:19 +00:00
|
|
|
if(entityA.v) {
|
2008-05-03 03:33:35 +00:00
|
|
|
Vector r, u, n;
|
|
|
|
if(workplane.v == Entity::FREE_IN_3D.v) {
|
|
|
|
r = gr; u = gu; n = gn;
|
|
|
|
} else {
|
2009-04-19 05:53:16 +00:00
|
|
|
r = SK.GetEntity(workplane)->Normal()->NormalU();
|
|
|
|
u = SK.GetEntity(workplane)->Normal()->NormalV();
|
2008-05-03 03:33:35 +00:00
|
|
|
n = r.Cross(u);
|
|
|
|
}
|
2008-04-30 08:14:32 +00:00
|
|
|
// For "at midpoint", this branch is always taken.
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *e = SK.GetEntity(entityA);
|
|
|
|
Vector a = SK.GetEntity(e->point[0])->PointGetNum();
|
|
|
|
Vector b = SK.GetEntity(e->point[1])->PointGetNum();
|
2008-04-23 07:29:19 +00:00
|
|
|
Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5));
|
2008-05-03 03:33:35 +00:00
|
|
|
Vector offset = (a.Minus(b)).Cross(n);
|
2008-04-30 08:14:32 +00:00
|
|
|
offset = offset.WithMagnitude(13/SS.GW.scale);
|
2008-05-01 06:53:50 +00:00
|
|
|
// Draw midpoint constraint on other side of line, so that
|
|
|
|
// a line can be midpoint and horizontal at same time.
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::AT_MIDPOINT) offset = offset.ScaledBy(-1);
|
2008-04-23 07:29:19 +00:00
|
|
|
|
|
|
|
if(dogd.drawing) {
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
const char *s = (type == Type::HORIZONTAL) ? "H" : (
|
|
|
|
(type == Type::VERTICAL) ? "V" : (
|
|
|
|
(type == Type::AT_MIDPOINT) ? "M" : NULL));
|
2009-07-03 20:55:57 +00:00
|
|
|
|
2016-03-02 17:15:28 +00:00
|
|
|
ssglWriteTextRefCenter(s, Style::DefaultTextHeight(),
|
2016-05-21 05:18:00 +00:00
|
|
|
m.Plus(offset), r, u, LineCallback, (void *)this);
|
2008-04-23 07:29:19 +00:00
|
|
|
} else {
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = m.Plus(offset);
|
|
|
|
Point2d ref = SS.GW.ProjectPoint(m.Plus(offset));
|
2008-04-23 07:29:19 +00:00
|
|
|
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-10);
|
|
|
|
}
|
|
|
|
} else {
|
2009-04-19 05:53:16 +00:00
|
|
|
Vector a = SK.GetEntity(ptA)->PointGetNum();
|
|
|
|
Vector b = SK.GetEntity(ptB)->PointGetNum();
|
2008-04-23 07:46:24 +00:00
|
|
|
|
2009-04-19 05:53:16 +00:00
|
|
|
Entity *w = SK.GetEntity(workplane);
|
2008-05-05 11:17:00 +00:00
|
|
|
Vector cu = w->Normal()->NormalU();
|
|
|
|
Vector cv = w->Normal()->NormalV();
|
|
|
|
Vector cn = w->Normal()->NormalN();
|
2008-04-23 07:29:19 +00:00
|
|
|
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < 2; i++) {
|
|
|
|
Vector o = (i == 0) ? a : b;
|
2008-04-23 07:46:24 +00:00
|
|
|
Vector oo = (i == 0) ? a.Minus(b) : b.Minus(a);
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
Vector d = (type == Type::HORIZONTAL) ? cu : cv;
|
2008-04-23 07:46:24 +00:00
|
|
|
if(oo.Dot(d) < 0) d = d.ScaledBy(-1);
|
|
|
|
|
2008-04-23 07:29:19 +00:00
|
|
|
Vector dp = cn.Cross(d);
|
|
|
|
d = d.WithMagnitude(14/SS.GW.scale);
|
|
|
|
Vector c = o.Minus(d);
|
|
|
|
LineDrawOrGetDistance(o, c);
|
|
|
|
d = d.WithMagnitude(3/SS.GW.scale);
|
|
|
|
dp = dp.WithMagnitude(2/SS.GW.scale);
|
|
|
|
if(dogd.drawing) {
|
|
|
|
glBegin(GL_QUADS);
|
2013-10-22 04:45:06 +00:00
|
|
|
ssglVertex3v((c.Plus(d)).Plus(dp));
|
|
|
|
ssglVertex3v((c.Minus(d)).Plus(dp));
|
|
|
|
ssglVertex3v((c.Minus(d)).Minus(dp));
|
|
|
|
ssglVertex3v((c.Plus(d)).Minus(dp));
|
2008-04-23 07:29:19 +00:00
|
|
|
glEnd();
|
|
|
|
} else {
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = c;
|
2008-04-23 07:29:19 +00:00
|
|
|
Point2d ref = SS.GW.ProjectPoint(c);
|
|
|
|
dogd.dmin = min(dogd.dmin, ref.DistanceTo(dogd.mp)-6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2008-04-23 07:29:19 +00:00
|
|
|
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
case Type::COMMENT: {
|
2015-03-26 00:34:28 +00:00
|
|
|
if(dogd.drawing && disp.style.v) {
|
2015-03-22 13:39:12 +00:00
|
|
|
ssglLineWidth(Style::Width(disp.style));
|
2013-10-22 04:45:06 +00:00
|
|
|
ssglColorRGB(Style::Color(disp.style));
|
2009-09-24 15:52:48 +00:00
|
|
|
}
|
2009-09-29 11:35:19 +00:00
|
|
|
Vector u, v;
|
|
|
|
if(workplane.v == Entity::FREE_IN_3D.v) {
|
|
|
|
u = gr;
|
|
|
|
v = gu;
|
|
|
|
} else {
|
|
|
|
EntityBase *norm = SK.GetEntity(workplane)->Normal();
|
|
|
|
u = norm->NormalU();
|
|
|
|
v = norm->NormalV();
|
|
|
|
}
|
2016-05-24 06:40:41 +00:00
|
|
|
if(refps) refps[0] = refps[1] = disp.offset;
|
2009-09-29 11:35:19 +00:00
|
|
|
DoLabel(disp.offset, labelPos, u, v);
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
return;
|
2009-09-29 11:35:19 +00:00
|
|
|
}
|
2008-04-14 10:28:32 +00:00
|
|
|
}
|
Enable exhaustive switch coverage warnings as an error, and use them.
Specifically, this enables -Wswitch=error on GCC/Clang and its MSVC
equivalent; the exact way it is handled varies slightly, but what
they all have in common is that in a switch statement over an
enumeration, any enumerand that is not explicitly (via case:) or
implicitly (via default:) handled in the switch triggers an error.
Moreover, we also change the switch statements in three ways:
* Switch statements that ought to be extended every time a new
enumerand is added (e.g. Entity::DrawOrGetDistance(), are changed
to explicitly list every single enumerand, and not have a
default: branch.
Note that the assertions are kept because it is legal for
a enumeration to have a value unlike any of its defined
enumerands, and we can e.g. read garbage from a file, or
an uninitialized variable. This requires some rearranging if
a default: branch is undesired.
* Switch statements that ought to only ever see a few select
enumerands, are changed to always assert in the default: branch.
* Switch statements that do something meaningful for a few
enumerands, and ignore everything else, are changed to do nothing
in a default: branch, under the assumption that changing them
every time an enumerand is added or removed would just result
in noise and catch no bugs.
This commit also removes the {Request,Entity,Constraint}::UNKNOWN and
Entity::DATUM_POINT enumerands, as those were just fancy names for
zeroes. They mess up switch exhaustiveness checks and most of the time
were not the best way to implement what they did anyway.
2016-05-25 06:55:50 +00:00
|
|
|
ssassert(false, "Unexpected constraint type");
|
2008-04-14 10:28:32 +00:00
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
void Constraint::Draw() {
|
2008-04-14 10:28:32 +00:00
|
|
|
dogd.drawing = true;
|
2009-07-03 20:55:57 +00:00
|
|
|
dogd.sel = NULL;
|
2016-05-07 10:54:44 +00:00
|
|
|
hStyle hs = GetStyle();
|
2009-09-17 07:32:36 +00:00
|
|
|
|
2016-02-21 19:07:58 +00:00
|
|
|
ssglLineWidth(Style::Width(hs));
|
|
|
|
ssglColorRGB(Style::Color(hs));
|
2009-09-17 07:32:36 +00:00
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
DrawOrGetDistance(NULL, NULL);
|
2008-04-14 10:28:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
double Constraint::GetDistance(Point2d mp) {
|
|
|
|
dogd.drawing = false;
|
2009-07-03 20:55:57 +00:00
|
|
|
dogd.sel = NULL;
|
2008-04-14 10:28:32 +00:00
|
|
|
dogd.mp = mp;
|
|
|
|
dogd.dmin = 1e12;
|
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
DrawOrGetDistance(NULL, NULL);
|
2015-03-29 00:30:52 +00:00
|
|
|
|
2008-04-14 10:28:32 +00:00
|
|
|
return dogd.dmin;
|
|
|
|
}
|
|
|
|
|
2016-05-05 05:54:05 +00:00
|
|
|
Vector Constraint::GetLabelPos() {
|
2008-04-21 10:12:04 +00:00
|
|
|
dogd.drawing = false;
|
2009-07-03 20:55:57 +00:00
|
|
|
dogd.sel = NULL;
|
2008-04-21 10:12:04 +00:00
|
|
|
dogd.mp.x = 0; dogd.mp.y = 0;
|
|
|
|
dogd.dmin = 1e12;
|
|
|
|
|
|
|
|
Vector p;
|
2016-05-24 06:40:41 +00:00
|
|
|
DrawOrGetDistance(&p, NULL);
|
2008-04-21 10:12:04 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
void Constraint::GetReferencePos(Vector *refps) {
|
2008-05-26 09:56:50 +00:00
|
|
|
dogd.drawing = false;
|
2009-07-03 20:55:57 +00:00
|
|
|
dogd.sel = NULL;
|
2008-05-26 09:56:50 +00:00
|
|
|
|
2016-05-24 06:40:41 +00:00
|
|
|
DrawOrGetDistance(NULL, refps);
|
2008-05-26 09:56:50 +00:00
|
|
|
}
|
|
|
|
|
2009-07-03 20:55:57 +00:00
|
|
|
void Constraint::GetEdges(SEdgeList *sel) {
|
|
|
|
dogd.drawing = true;
|
|
|
|
dogd.sel = sel;
|
2016-05-24 06:40:41 +00:00
|
|
|
DrawOrGetDistance(NULL, NULL);
|
2009-07-03 20:55:57 +00:00
|
|
|
dogd.sel = NULL;
|
|
|
|
}
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool Constraint::IsStylable() const {
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
if(type == Type::COMMENT) return true;
|
2016-03-25 08:45:49 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-05-07 10:54:44 +00:00
|
|
|
hStyle Constraint::GetStyle() const {
|
|
|
|
if(disp.style.v != 0) return disp.style;
|
|
|
|
return { Style::CONSTRAINT };
|
|
|
|
}
|
|
|
|
|
2016-05-21 05:18:00 +00:00
|
|
|
bool Constraint::HasLabel() const {
|
2016-04-18 06:40:42 +00:00
|
|
|
switch(type) {
|
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.
2016-05-20 08:31:20 +00:00
|
|
|
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:
|
2016-04-18 06:40:42 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|