Annotate constants passed as boolean function arguments.
This is to ensure that: * it is clear, when looking at the point of usage, what is the purpose of "true" or "false"; * when refactoring, a simple search will bring up any places that need to be changed. Also, argument names were synchronized between declaration and implementation. As an exception, these are not annotated: * Printf(/*halfLine=*/), to avoid pointless churn.
This commit is contained in:
parent
8aab0160d3
commit
5791310bb1
@ -118,7 +118,7 @@ alt:
|
|||||||
} else {
|
} else {
|
||||||
// I suppose this actually is allowed to happen, if the coplanar
|
// I suppose this actually is allowed to happen, if the coplanar
|
||||||
// face is the leaf, and all of its neighbors are earlier in tree?
|
// face is the leaf, and all of its neighbors are earlier in tree?
|
||||||
InsertInPlane(false, tr, instead);
|
InsertInPlane(/*pos2=*/false, tr, instead);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
instead->atLeastOneDiscarded = true;
|
instead->atLeastOneDiscarded = true;
|
||||||
@ -555,7 +555,7 @@ void SBsp2::InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3
|
|||||||
if(pos) {
|
if(pos) {
|
||||||
pos->InsertTriangle(tr, m, bsp3);
|
pos->InsertTriangle(tr, m, bsp3);
|
||||||
} else {
|
} else {
|
||||||
bsp3->InsertInPlane(true, tr, m);
|
bsp3->InsertInPlane(/*pos2=*/true, tr, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -563,7 +563,7 @@ void SBsp2::InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3
|
|||||||
if(neg) {
|
if(neg) {
|
||||||
neg->InsertTriangle(tr, m, bsp3);
|
neg->InsertTriangle(tr, m, bsp3);
|
||||||
} else {
|
} else {
|
||||||
bsp3->InsertInPlane(false, tr, m);
|
bsp3->InsertInPlane(/*pos2=*/false, tr, m);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
|
|||||||
|
|
||||||
ClipboardRequest *cr;
|
ClipboardRequest *cr;
|
||||||
for(cr = SS.clipboard.r.First(); cr; cr = SS.clipboard.r.NextAfter(cr)) {
|
for(cr = SS.clipboard.r.First(); cr; cr = SS.clipboard.r.NextAfter(cr)) {
|
||||||
hRequest hr = AddRequest(cr->type, false);
|
hRequest hr = AddRequest(cr->type, /*rememberForUndo=*/false);
|
||||||
Request *r = SK.GetRequest(hr);
|
Request *r = SK.GetRequest(hr);
|
||||||
r->extraPoints = cr->extraPoints;
|
r->extraPoints = cr->extraPoints;
|
||||||
r->style = cr->style;
|
r->style = cr->style;
|
||||||
@ -284,7 +284,7 @@ bool TextWindow::EditControlDoneForPaste(const char *s) {
|
|||||||
Expr *e;
|
Expr *e;
|
||||||
switch(edit.meaning) {
|
switch(edit.meaning) {
|
||||||
case Edit::PASTE_TIMES_REPEATED: {
|
case Edit::PASTE_TIMES_REPEATED: {
|
||||||
e = Expr::From(s, true);
|
e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(!e) break;
|
if(!e) break;
|
||||||
int v = (int)e->Eval();
|
int v = (int)e->Eval();
|
||||||
if(v > 0) {
|
if(v > 0) {
|
||||||
@ -295,13 +295,13 @@ bool TextWindow::EditControlDoneForPaste(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::PASTE_ANGLE:
|
case Edit::PASTE_ANGLE:
|
||||||
e = Expr::From(s, true);
|
e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(!e) break;
|
if(!e) break;
|
||||||
shown.paste.theta = WRAP_SYMMETRIC((e->Eval())*PI/180, 2*PI);
|
shown.paste.theta = WRAP_SYMMETRIC((e->Eval())*PI/180, 2*PI);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Edit::PASTE_SCALE: {
|
case Edit::PASTE_SCALE: {
|
||||||
e = Expr::From(s, true);
|
e = Expr::From(s, /*popUpError=*/true);
|
||||||
double v = e->Eval();
|
double v = e->Eval();
|
||||||
if(fabs(v) > 1e-6) {
|
if(fabs(v) > 1e-6) {
|
||||||
shown.paste.scale = v;
|
shown.paste.scale = v;
|
||||||
|
@ -378,7 +378,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::EXPORT_SCALE: {
|
case Edit::EXPORT_SCALE: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = e->Eval();
|
double ev = e->Eval();
|
||||||
if(fabs(ev) < 0.001 || isnan(ev)) {
|
if(fabs(ev) < 0.001 || isnan(ev)) {
|
||||||
@ -390,7 +390,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::EXPORT_OFFSET: {
|
case Edit::EXPORT_OFFSET: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = SS.ExprToMm(e);
|
double ev = SS.ExprToMm(e);
|
||||||
if(isnan(ev) || ev < 0) {
|
if(isnan(ev) || ev < 0) {
|
||||||
@ -402,7 +402,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::CANVAS_SIZE: {
|
case Edit::CANVAS_SIZE: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(!e) {
|
if(!e) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -421,23 +421,23 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::G_CODE_DEPTH: {
|
case Edit::G_CODE_DEPTH: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) SS.gCode.depth = (float)SS.ExprToMm(e);
|
if(e) SS.gCode.depth = (float)SS.ExprToMm(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::G_CODE_PASSES: {
|
case Edit::G_CODE_PASSES: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) SS.gCode.passes = (int)(e->Eval());
|
if(e) SS.gCode.passes = (int)(e->Eval());
|
||||||
SS.gCode.passes = max(1, min(1000, SS.gCode.passes));
|
SS.gCode.passes = max(1, min(1000, SS.gCode.passes));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::G_CODE_FEED: {
|
case Edit::G_CODE_FEED: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) SS.gCode.feed = (float)SS.ExprToMm(e);
|
if(e) SS.gCode.feed = (float)SS.ExprToMm(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::G_CODE_PLUNGE_FEED: {
|
case Edit::G_CODE_PLUNGE_FEED: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) SS.gCode.plungeFeed = (float)SS.ExprToMm(e);
|
if(e) SS.gCode.plungeFeed = (float)SS.ExprToMm(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ void Constraint::DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::AddConstraint(Constraint *c) {
|
hConstraint Constraint::AddConstraint(Constraint *c) {
|
||||||
return AddConstraint(c, true);
|
return AddConstraint(c, /*rememberForUndo=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
|
hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) {
|
||||||
@ -103,16 +103,16 @@ hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity pt
|
|||||||
c.entityB = entityB;
|
c.entityB = entityB;
|
||||||
c.other = other;
|
c.other = other;
|
||||||
c.other2 = other2;
|
c.other2 = other2;
|
||||||
return AddConstraint(&c, false);
|
return AddConstraint(&c, /*rememberForUndo=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA){
|
hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA){
|
||||||
return Constrain(type, ptA, ptB, entityA, Entity::NO_ENTITY, false, false);
|
return Constrain(type, ptA, ptB, entityA, Entity::NO_ENTITY, /*other=*/false, /*other2=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
|
hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) {
|
||||||
return Constrain(Type::POINTS_COINCIDENT, ptA, ptB,
|
return Constrain(Type::POINTS_COINCIDENT, ptA, ptB,
|
||||||
Entity::NO_ENTITY, Entity::NO_ENTITY, false, false);
|
Entity::NO_ENTITY, Entity::NO_ENTITY, /*other=*/false, /*other2=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Constraint::MenuConstrain(Command id) {
|
void Constraint::MenuConstrain(Command id) {
|
||||||
@ -516,7 +516,7 @@ void Constraint::MenuConstrain(Command id) {
|
|||||||
|
|
||||||
nfree->NormalForceTo(Quaternion::From(fu, fv));
|
nfree->NormalForceTo(Quaternion::From(fu, fv));
|
||||||
}
|
}
|
||||||
AddConstraint(&c, false);
|
AddConstraint(&c, /*rememberForUndo=*/false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,7 +709,7 @@ nogrid:;
|
|||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
// And the naked edges, if the user did Analyze -> Show Naked Edges.
|
// And the naked edges, if the user did Analyze -> Show Naked Edges.
|
||||||
ssglDrawEdges(&(SS.nakedEdges), true, { Style::DRAW_ERROR });
|
ssglDrawEdges(&(SS.nakedEdges), /*endpointsToo=*/true, { Style::DRAW_ERROR });
|
||||||
|
|
||||||
// Then redraw whatever the mouse is hovering over, highlighted.
|
// Then redraw whatever the mouse is hovering over, highlighted.
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
@ -28,7 +28,7 @@ void Constraint::LineDrawOrGetDistance(Vector a, Vector b) {
|
|||||||
Point2d ap = SS.GW.ProjectPoint(a);
|
Point2d ap = SS.GW.ProjectPoint(a);
|
||||||
Point2d bp = SS.GW.ProjectPoint(b);
|
Point2d bp = SS.GW.ProjectPoint(b);
|
||||||
|
|
||||||
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), true);
|
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true);
|
||||||
dogd.dmin = min(dogd.dmin, d);
|
dogd.dmin = min(dogd.dmin, d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ void Constraint::DoLabel(Vector ref, Vector *labelPos, Vector gr, Vector gu) {
|
|||||||
l = max(l, 5/SS.GW.scale);
|
l = max(l, 5/SS.GW.scale);
|
||||||
Point2d a = SS.GW.ProjectPoint(ref.Minus(gr.WithMagnitude(l)));
|
Point2d a = SS.GW.ProjectPoint(ref.Minus(gr.WithMagnitude(l)));
|
||||||
Point2d b = SS.GW.ProjectPoint(ref.Plus (gr.WithMagnitude(l)));
|
Point2d b = SS.GW.ProjectPoint(ref.Plus (gr.WithMagnitude(l)));
|
||||||
double d = dogd.mp.DistanceToLine(a, b.Minus(a), true);
|
double d = dogd.mp.DistanceToLine(a, b.Minus(a), /*asSegment=*/true);
|
||||||
|
|
||||||
dogd.dmin = min(dogd.dmin, d - (th / 2));
|
dogd.dmin = min(dogd.dmin, d - (th / 2));
|
||||||
}
|
}
|
||||||
@ -432,7 +432,7 @@ void Constraint::DoArcForAngle(Vector a0, Vector da, Vector b0, Vector db,
|
|||||||
dna.ScaledBy(r*sin(theta))).Plus(pi);
|
dna.ScaledBy(r*sin(theta))).Plus(pi);
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
if(trim) {
|
if(trim) {
|
||||||
DoLineTrimmedAgainstBox(*ref, prev, p, false, gr, gu, swidth, sheight);
|
DoLineTrimmedAgainstBox(*ref, prev, p, /*extend=*/false, gr, gu, swidth, sheight);
|
||||||
} else {
|
} else {
|
||||||
LineDrawOrGetDistance(prev, p);
|
LineDrawOrGetDistance(prev, p);
|
||||||
}
|
}
|
||||||
@ -534,7 +534,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
|
|||||||
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
|
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset);
|
||||||
if(refps) refps[0] = refps[1] = ref;
|
if(refps) refps[0] = refps[1] = ref;
|
||||||
|
|
||||||
DoLineWithArrows(ref, ap, bp, false);
|
DoLineWithArrows(ref, ap, bp, /*onlyOneExt=*/false);
|
||||||
DoLabel(ref, labelPos, gr, gu);
|
DoLabel(ref, labelPos, gr, gu);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -554,7 +554,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
|
|||||||
StippledLine(ap, bpp);
|
StippledLine(ap, bpp);
|
||||||
StippledLine(bp, bpp);
|
StippledLine(bp, bpp);
|
||||||
|
|
||||||
DoLineWithArrows(ref, ap, bpp, false);
|
DoLineWithArrows(ref, ap, bpp, /*onlyOneExt=*/false);
|
||||||
DoLabel(ref, labelPos, gr, gu);
|
DoLabel(ref, labelPos, gr, gu);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -579,7 +579,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
|
|||||||
if(refps) refps[0] = refps[1] = ref;
|
if(refps) refps[0] = refps[1] = ref;
|
||||||
|
|
||||||
if(!pt.Equals(closest)) {
|
if(!pt.Equals(closest)) {
|
||||||
DoLineWithArrows(ref, pt, closest, true);
|
DoLineWithArrows(ref, pt, closest, /*onlyOneExt=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoLabel(ref, labelPos, gr, gu);
|
DoLabel(ref, labelPos, gr, gu);
|
||||||
@ -607,7 +607,7 @@ void Constraint::DrawOrGetDistance(Vector *labelPos, Vector *refps) {
|
|||||||
DoLabel(ref, labelPos, gr, gu);
|
DoLabel(ref, labelPos, gr, gu);
|
||||||
|
|
||||||
if(!pt.Equals(closest)) {
|
if(!pt.Equals(closest)) {
|
||||||
DoLineWithArrows(ref, pt, closest, true);
|
DoLineWithArrows(ref, pt, closest, /*onlyOneExt=*/true);
|
||||||
|
|
||||||
// Extensions to line
|
// Extensions to line
|
||||||
double pixels = 1.0 / SS.GW.scale;
|
double pixels = 1.0 / SS.GW.scale;
|
||||||
|
@ -29,7 +29,7 @@ void Entity::LineDrawOrGetDistance(Vector a, Vector b, bool maybeFat, int data)
|
|||||||
Point2d ap = SS.GW.ProjectPoint(a);
|
Point2d ap = SS.GW.ProjectPoint(a);
|
||||||
Point2d bp = SS.GW.ProjectPoint(b);
|
Point2d bp = SS.GW.ProjectPoint(b);
|
||||||
|
|
||||||
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), true);
|
double d = dogd.mp.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true);
|
||||||
// A little bit easier to select in the active group
|
// A little bit easier to select in the active group
|
||||||
if(group.v == SS.GW.activeGroup.v) d -= 1;
|
if(group.v == SS.GW.activeGroup.v) d -= 1;
|
||||||
if(d < dogd.dmin) {
|
if(d < dogd.dmin) {
|
||||||
@ -453,11 +453,11 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Type::CUBIC:
|
case Type::CUBIC:
|
||||||
ComputeInterpolatingSpline(sbl, false);
|
ComputeInterpolatingSpline(sbl, /*periodic=*/false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type::CUBIC_PERIODIC:
|
case Type::CUBIC_PERIODIC:
|
||||||
ComputeInterpolatingSpline(sbl, true);
|
ComputeInterpolatingSpline(sbl, /*periodic=*/true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Type::CIRCLE:
|
case Type::CIRCLE:
|
||||||
@ -727,7 +727,7 @@ void Entity::DrawOrGetDistance() {
|
|||||||
dogd.data = -1;
|
dogd.data = -1;
|
||||||
for(int i = 0; i < sel->l.n; i++) {
|
for(int i = 0; i < sel->l.n; i++) {
|
||||||
SEdge *se = &(sel->l.elem[i]);
|
SEdge *se = &(sel->l.elem[i]);
|
||||||
LineDrawOrGetDistance(se->a, se->b, true, se->auxB);
|
LineDrawOrGetDistance(se->a, se->b, /*maybeFat=*/true, se->auxB);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ public:
|
|||||||
static bool BoundingBoxesDisjoint(Vector amax, Vector amin,
|
static bool BoundingBoxesDisjoint(Vector amax, Vector amin,
|
||||||
Vector bmax, Vector bmin);
|
Vector bmax, Vector bmin);
|
||||||
static bool BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
static bool BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
||||||
Vector p0, Vector p1, bool segment);
|
Vector p0, Vector p1, bool asSegment);
|
||||||
bool OutsideAndNotOn(Vector maxv, Vector minv) const;
|
bool OutsideAndNotOn(Vector maxv, Vector minv) const;
|
||||||
Vector InPerspective(Vector u, Vector v, Vector n,
|
Vector InPerspective(Vector u, Vector v, Vector n,
|
||||||
Vector origin, double cameraTan) const;
|
Vector origin, double cameraTan) const;
|
||||||
@ -134,7 +134,7 @@ public:
|
|||||||
double DivPivoting(Point2d delta) const;
|
double DivPivoting(Point2d delta) const;
|
||||||
double Dot(Point2d p) const;
|
double Dot(Point2d p) const;
|
||||||
double DistanceTo(const Point2d &p) const;
|
double DistanceTo(const Point2d &p) const;
|
||||||
double DistanceToLine(const Point2d &p0, const Point2d &dp, bool segment) const;
|
double DistanceToLine(const Point2d &p0, const Point2d &dp, bool asSegment) const;
|
||||||
double Angle() const;
|
double Angle() const;
|
||||||
double AngleTo(const Point2d &p) const;
|
double AngleTo(const Point2d &p) const;
|
||||||
double Magnitude() const;
|
double Magnitude() const;
|
||||||
|
@ -110,7 +110,7 @@ void SolveSpaceUI::ExportSectionTo(const std::string &filename) {
|
|||||||
bl.Clear();
|
bl.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool wireframe) {
|
void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool exportWireframe) {
|
||||||
int i;
|
int i;
|
||||||
SEdgeList edges = {};
|
SEdgeList edges = {};
|
||||||
SBezierList beziers = {};
|
SBezierList beziers = {};
|
||||||
@ -168,7 +168,7 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const std::string &filename, bool wir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wireframe) {
|
if(exportWireframe) {
|
||||||
Vector u = Vector::From(1.0, 0.0, 0.0),
|
Vector u = Vector::From(1.0, 0.0, 0.0),
|
||||||
v = Vector::From(0.0, 1.0, 0.0),
|
v = Vector::From(0.0, 1.0, 0.0),
|
||||||
n = Vector::From(0.0, 0.0, 1.0),
|
n = Vector::From(0.0, 0.0, 1.0),
|
||||||
@ -659,8 +659,8 @@ void VectorFileWriter::OutputLinesAndMesh(SBezierLoopSetSet *sblss, SMesh *sm) {
|
|||||||
hStyle hs = { (uint32_t)b->auxA };
|
hStyle hs = { (uint32_t)b->auxA };
|
||||||
Style *stl = Style::Get(hs);
|
Style *stl = Style::Get(hs);
|
||||||
double lineWidth = Style::WidthMm(b->auxA)*s;
|
double lineWidth = Style::WidthMm(b->auxA)*s;
|
||||||
RgbaColor strokeRgb = Style::Color(hs, true);
|
RgbaColor strokeRgb = Style::Color(hs, /*forExport=*/true);
|
||||||
RgbaColor fillRgb = Style::FillColor(hs, true);
|
RgbaColor fillRgb = Style::FillColor(hs, /*forExport=*/true);
|
||||||
|
|
||||||
StartPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs);
|
StartPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs);
|
||||||
for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
|
for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) {
|
||||||
|
@ -251,14 +251,14 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) {
|
|||||||
|
|
||||||
List<int> listOfLoops = {};
|
List<int> listOfLoops = {};
|
||||||
// Create the face outer boundary from the outer loop.
|
// Create the face outer boundary from the outer loop.
|
||||||
int fob = ExportCurveLoop(loop, false);
|
int fob = ExportCurveLoop(loop, /*inner=*/false);
|
||||||
listOfLoops.Add(&fob);
|
listOfLoops.Add(&fob);
|
||||||
|
|
||||||
// And create the face inner boundaries from any inner loops that
|
// And create the face inner boundaries from any inner loops that
|
||||||
// lie within this contour.
|
// lie within this contour.
|
||||||
loop = sbls->l.NextAfter(loop);
|
loop = sbls->l.NextAfter(loop);
|
||||||
for(; loop; loop = sbls->l.NextAfter(loop)) {
|
for(; loop; loop = sbls->l.NextAfter(loop)) {
|
||||||
int fib = ExportCurveLoop(loop, true);
|
int fib = ExportCurveLoop(loop, /*inner=*/true);
|
||||||
listOfLoops.Add(&fib);
|
listOfLoops.Add(&fib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ public:
|
|||||||
|
|
||||||
void assignEntityDefaults(DRW_Entity *entity, hStyle hs) {
|
void assignEntityDefaults(DRW_Entity *entity, hStyle hs) {
|
||||||
Style *s = Style::Get(hs);
|
Style *s = Style::Get(hs);
|
||||||
RgbaColor color = s->Color(hs, true);
|
RgbaColor color = s->Color(hs, /*forExport=*/true);
|
||||||
entity->color24 = color.ToPackedIntBGRA();
|
entity->color24 = color.ToPackedIntBGRA();
|
||||||
entity->color = findDxfColor(color);
|
entity->color = findDxfColor(color);
|
||||||
entity->layer = s->DescriptionString();
|
entity->layer = s->DescriptionString();
|
||||||
@ -692,7 +692,7 @@ void DxfFileWriter::Bezier(SBezier *sb) {
|
|||||||
void DxfFileWriter::FinishAndCloseFile() {
|
void DxfFileWriter::FinishAndCloseFile() {
|
||||||
dxfRW dxf(filename.c_str());
|
dxfRW dxf(filename.c_str());
|
||||||
DxfWriteInterface interface(this, &dxf);
|
DxfWriteInterface interface(this, &dxf);
|
||||||
dxf.write(&interface, DRW::AC1021, false);
|
dxf.write(&interface, DRW::AC1021, /*bin=*/false);
|
||||||
paths.clear();
|
paths.clear();
|
||||||
constraint = NULL;
|
constraint = NULL;
|
||||||
}
|
}
|
||||||
@ -1123,7 +1123,7 @@ void SvgFileWriter::StartFile() {
|
|||||||
fprintf(f, "}\r\n");
|
fprintf(f, "}\r\n");
|
||||||
for(int i = 0; i < SK.style.n; i++) {
|
for(int i = 0; i < SK.style.n; i++) {
|
||||||
Style *s = &SK.style.elem[i];
|
Style *s = &SK.style.elem[i];
|
||||||
RgbaColor strokeRgb = Style::Color(s->h, true);
|
RgbaColor strokeRgb = Style::Color(s->h, /*forExport=*/true);
|
||||||
StipplePattern pattern = Style::PatternType(s->h);
|
StipplePattern pattern = Style::PatternType(s->h);
|
||||||
double stippleScale = Style::StippleScaleMm(s->h);
|
double stippleScale = Style::StippleScaleMm(s->h);
|
||||||
|
|
||||||
|
@ -290,7 +290,7 @@ bool SolveSpaceUI::SaveToFile(const std::string &filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
for(i = 0; i < SK.entity.n; i++) {
|
||||||
(SK.entity.elem[i]).CalculateNumerical(true);
|
(SK.entity.elem[i]).CalculateNumerical(/*forExport=*/true);
|
||||||
sv.e = SK.entity.elem[i];
|
sv.e = SK.entity.elem[i];
|
||||||
SaveUsingTable('e');
|
SaveUsingTable('e');
|
||||||
fprintf(fh, "AddEntity\n\n");
|
fprintf(fh, "AddEntity\n\n");
|
||||||
|
@ -520,7 +520,7 @@ void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) {
|
|||||||
MarkDraggedParams();
|
MarkDraggedParams();
|
||||||
g->solved.remove.Clear();
|
g->solved.remove.Clear();
|
||||||
SolveResult how = sys.Solve(g, &(g->solved.dof),
|
SolveResult how = sys.Solve(g, &(g->solved.dof),
|
||||||
&(g->solved.remove), true, andFindFree);
|
&(g->solved.remove), /*andFindBad=*/true, andFindFree);
|
||||||
bool isOkay = how == SolveResult::OKAY ||
|
bool isOkay = how == SolveResult::OKAY ||
|
||||||
(g->allowRedundant && how == SolveResult::REDUNDANT_OKAY);
|
(g->allowRedundant && how == SolveResult::REDUNDANT_OKAY);
|
||||||
if(!isOkay || (isOkay && !g->IsSolvedOkay()))
|
if(!isOkay || (isOkay && !g->IsSolvedOkay()))
|
||||||
|
@ -260,7 +260,7 @@ void ssglColorRGBa(RgbaColor rgb, double a)
|
|||||||
if(!ColorLocked) glColor4d(rgb.redF(), rgb.greenF(), rgb.blueF(), a);
|
if(!ColorLocked) glColor4d(rgb.redF(), rgb.greenF(), rgb.blueF(), a);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Stipple(bool forSel)
|
static void Stipple(bool forSelection)
|
||||||
{
|
{
|
||||||
static bool Init;
|
static bool Init;
|
||||||
const int BYTES = (32*32)/8;
|
const int BYTES = (32*32)/8;
|
||||||
@ -284,19 +284,19 @@ static void Stipple(bool forSel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_POLYGON_STIPPLE);
|
glEnable(GL_POLYGON_STIPPLE);
|
||||||
if(forSel) {
|
if(forSelection) {
|
||||||
glPolygonStipple(SelMask);
|
glPolygonStipple(SelMask);
|
||||||
} else {
|
} else {
|
||||||
glPolygonStipple(HoverMask);
|
glPolygonStipple(HoverMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StippleTriangle(STriangle *tr, bool s, RgbaColor rgb)
|
static void StippleTriangle(STriangle *tr, bool forSelection, RgbaColor rgb)
|
||||||
{
|
{
|
||||||
glEnd();
|
glEnd();
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
ssglColorRGB(rgb);
|
ssglColorRGB(rgb);
|
||||||
Stipple(s);
|
Stipple(forSelection);
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
ssglVertex3v(tr->a);
|
ssglVertex3v(tr->a);
|
||||||
ssglVertex3v(tr->b);
|
ssglVertex3v(tr->b);
|
||||||
@ -357,10 +357,10 @@ void ssglFillMesh(bool useSpecColor, RgbaColor specColor,
|
|||||||
if((s1 != 0 && tr->meta.face == s1) ||
|
if((s1 != 0 && tr->meta.face == s1) ||
|
||||||
(s2 != 0 && tr->meta.face == s2))
|
(s2 != 0 && tr->meta.face == s2))
|
||||||
{
|
{
|
||||||
StippleTriangle(tr, true, rgbSelected);
|
StippleTriangle(tr, /*forSelection=*/true, rgbSelected);
|
||||||
}
|
}
|
||||||
if(h != 0 && tr->meta.face == h) {
|
if(h != 0 && tr->meta.face == h) {
|
||||||
StippleTriangle(tr, false, rgbHovered);
|
StippleTriangle(tr, /*forSelection=*/false, rgbHovered);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
@ -624,7 +624,8 @@ static void LoadBitmapFont() {
|
|||||||
BuiltinBitmapFont.AddGlyph(0xE006, LoadPNG("fonts/private/6-stipple-dash.png"));
|
BuiltinBitmapFont.AddGlyph(0xE006, LoadPNG("fonts/private/6-stipple-dash.png"));
|
||||||
BuiltinBitmapFont.AddGlyph(0xE007, LoadPNG("fonts/private/7-stipple-zigzag.png"));
|
BuiltinBitmapFont.AddGlyph(0xE007, LoadPNG("fonts/private/7-stipple-zigzag.png"));
|
||||||
// Unifont doesn't have a glyph for U+0020.
|
// Unifont doesn't have a glyph for U+0020.
|
||||||
BuiltinBitmapFont.AddGlyph(0x20, Pixmap({ 8, 16, 8*3, false, std::vector<uint8_t>(8*16*3) }));
|
BuiltinBitmapFont.AddGlyph(0x20,
|
||||||
|
Pixmap({ 8, 16, 8*3, /*hasAlpha=*/false, std::vector<uint8_t>(8*16*3) }));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssglInitializeBitmapFont()
|
void ssglInitializeBitmapFont()
|
||||||
|
@ -665,16 +665,16 @@ void GraphicsWindow::EnsureValidActives() {
|
|||||||
RadioMenuByCmd(Command::UNITS_INCHES, SS.viewUnits == Unit::INCHES);
|
RadioMenuByCmd(Command::UNITS_INCHES, SS.viewUnits == Unit::INCHES);
|
||||||
|
|
||||||
ShowTextWindow(SS.GW.showTextWindow);
|
ShowTextWindow(SS.GW.showTextWindow);
|
||||||
CheckMenuByCmd(Command::SHOW_TEXT_WND, SS.GW.showTextWindow);
|
CheckMenuByCmd(Command::SHOW_TEXT_WND, /*checked=*/SS.GW.showTextWindow);
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
CheckMenuByCmd(Command::SHOW_MENU_BAR, MenuBarIsVisible());
|
CheckMenuByCmd(Command::SHOW_MENU_BAR, /*checked=*/MenuBarIsVisible());
|
||||||
#endif
|
#endif
|
||||||
CheckMenuByCmd(Command::SHOW_TOOLBAR, SS.showToolbar);
|
CheckMenuByCmd(Command::SHOW_TOOLBAR, /*checked=*/SS.showToolbar);
|
||||||
CheckMenuByCmd(Command::PERSPECTIVE_PROJ, SS.usePerspectiveProj);
|
CheckMenuByCmd(Command::PERSPECTIVE_PROJ, /*checked=*/SS.usePerspectiveProj);
|
||||||
CheckMenuByCmd(Command::SHOW_GRID, SS.GW.showSnapGrid);
|
CheckMenuByCmd(Command::SHOW_GRID,/*checked=*/SS.GW.showSnapGrid);
|
||||||
#if defined(HAVE_GTK) || defined(__APPLE__)
|
#if defined(HAVE_GTK) || defined(__APPLE__)
|
||||||
CheckMenuByCmd(Command::FULL_SCREEN, FullScreenIsActive());
|
CheckMenuByCmd(Command::FULL_SCREEN, /*checked=*/FullScreenIsActive());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(change) SS.ScheduleShowTW();
|
if(change) SS.ScheduleShowTW();
|
||||||
@ -698,7 +698,7 @@ bool GraphicsWindow::LockedInWorkplane() {
|
|||||||
void GraphicsWindow::ForceTextWindowShown() {
|
void GraphicsWindow::ForceTextWindowShown() {
|
||||||
if(!showTextWindow) {
|
if(!showTextWindow) {
|
||||||
showTextWindow = true;
|
showTextWindow = true;
|
||||||
CheckMenuByCmd(Command::SHOW_TEXT_WND, true);
|
CheckMenuByCmd(Command::SHOW_TEXT_WND, /*checked=*/true);
|
||||||
ShowTextWindow(true);
|
ShowTextWindow(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,18 +411,18 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
|
|
||||||
if(e->IsPoint()) pt = e->h;
|
if(e->IsPoint()) pt = e->h;
|
||||||
|
|
||||||
e->CalculateNumerical(false);
|
e->CalculateNumerical(/*forExport=*/false);
|
||||||
hEntity he = e->h; e = NULL;
|
hEntity he = e->h; e = NULL;
|
||||||
// As soon as I call CopyEntity, e may become invalid! That
|
// As soon as I call CopyEntity, e may become invalid! That
|
||||||
// adds entities, which may cause a realloc.
|
// adds entities, which may cause a realloc.
|
||||||
CopyEntity(entity, SK.GetEntity(he), ai, REMAP_BOTTOM,
|
CopyEntity(entity, SK.GetEntity(he), ai, REMAP_BOTTOM,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
true, false);
|
/*asTrans=*/true, /*asAxisAngle=*/false);
|
||||||
CopyEntity(entity, SK.GetEntity(he), af, REMAP_TOP,
|
CopyEntity(entity, SK.GetEntity(he), af, REMAP_TOP,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
true, false);
|
/*asTrans=*/true, /*asAxisAngle=*/false);
|
||||||
MakeExtrusionLines(entity, he);
|
MakeExtrusionLines(entity, he);
|
||||||
}
|
}
|
||||||
// Remapped versions of that arbitrary point will be used to
|
// Remapped versions of that arbitrary point will be used to
|
||||||
@ -446,7 +446,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group.v != opA.v) continue;
|
if(e->group.v != opA.v) continue;
|
||||||
|
|
||||||
e->CalculateNumerical(false);
|
e->CalculateNumerical(/*forExport=*/false);
|
||||||
hEntity he = e->h;
|
hEntity he = e->h;
|
||||||
|
|
||||||
// As soon as I call CopyEntity, e may become invalid! That
|
// As soon as I call CopyEntity, e may become invalid! That
|
||||||
@ -454,17 +454,17 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
CopyEntity(entity, SK.GetEntity(predef.origin), 0, ai,
|
CopyEntity(entity, SK.GetEntity(predef.origin), 0, ai,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
true, false);
|
/*asTrans=*/true, /*asAxisAngle=*/false);
|
||||||
|
|
||||||
CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_START,
|
CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_START,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
true, false);
|
/*asTrans=*/true, /*asAxisAngle=*/false);
|
||||||
|
|
||||||
CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_END,
|
CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_END,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
true, false);
|
/*asTrans=*/true, /*asAxisAngle=*/false);
|
||||||
|
|
||||||
MakeLatheCircles(entity, param, he, axis_pos, axis_dir, ai);
|
MakeLatheCircles(entity, param, he, axis_pos, axis_dir, ai);
|
||||||
ai++;
|
ai++;
|
||||||
@ -488,13 +488,13 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group.v != opA.v) continue;
|
if(e->group.v != opA.v) continue;
|
||||||
|
|
||||||
e->CalculateNumerical(false);
|
e->CalculateNumerical(/*forExport=*/false);
|
||||||
CopyEntity(entity, e,
|
CopyEntity(entity, e,
|
||||||
a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)),
|
a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)),
|
||||||
(a == (n - 1)) ? REMAP_LAST : a,
|
(a == (n - 1)) ? REMAP_LAST : a,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM,
|
||||||
true, false);
|
/*asTrans=*/true, /*asAxisAngle=*/false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -520,13 +520,13 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group.v != opA.v) continue;
|
if(e->group.v != opA.v) continue;
|
||||||
|
|
||||||
e->CalculateNumerical(false);
|
e->CalculateNumerical(/*forExport=*/false);
|
||||||
CopyEntity(entity, e,
|
CopyEntity(entity, e,
|
||||||
a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)),
|
a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)),
|
||||||
(a == (n - 1)) ? REMAP_LAST : a,
|
(a == (n - 1)) ? REMAP_LAST : a,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
h.param(3), h.param(4), h.param(5), h.param(6),
|
h.param(3), h.param(4), h.param(5), h.param(6),
|
||||||
false, true);
|
/*asTrans=*/false, /*asAxisAngle=*/true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -547,7 +547,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
CopyEntity(entity, ie, 0, 0,
|
CopyEntity(entity, ie, 0, 0,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
h.param(3), h.param(4), h.param(5), h.param(6),
|
h.param(3), h.param(4), h.param(5), h.param(6),
|
||||||
false, false);
|
/*asTrans=*/false, /*asAxisAngle=*/false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -503,12 +503,12 @@ void Group::DrawDisplayItems(Group::Type t) {
|
|||||||
if(SS.GW.showHdnLines) {
|
if(SS.GW.showHdnLines) {
|
||||||
ssglDepthRangeOffset(0);
|
ssglDepthRangeOffset(0);
|
||||||
glDepthFunc(GL_GREATER);
|
glDepthFunc(GL_GREATER);
|
||||||
ssglDrawEdges(&displayEdges, false, { Style::HIDDEN_EDGE });
|
ssglDrawEdges(&displayEdges, /*endpointsToo=*/false, { Style::HIDDEN_EDGE });
|
||||||
ssglDrawOutlines(&displayOutlines, projDir, { Style::HIDDEN_EDGE });
|
ssglDrawOutlines(&displayOutlines, projDir, { Style::HIDDEN_EDGE });
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
}
|
}
|
||||||
ssglDepthRangeOffset(2);
|
ssglDepthRangeOffset(2);
|
||||||
ssglDrawEdges(&displayEdges, false, { Style::SOLID_EDGE });
|
ssglDrawEdges(&displayEdges, /*endpointsToo=*/false, { Style::SOLID_EDGE });
|
||||||
if(SS.GW.showOutlines) {
|
if(SS.GW.showOutlines) {
|
||||||
ssglDrawOutlines(&displayOutlines, projDir, { Style::OUTLINE });
|
ssglDrawOutlines(&displayOutlines, projDir, { Style::OUTLINE });
|
||||||
} else {
|
} else {
|
||||||
|
@ -124,7 +124,7 @@ public:
|
|||||||
if(reversed) std::swap(p0, p1);
|
if(reversed) std::swap(p0, p1);
|
||||||
blockTransformArc(¢er, &p0, &p1);
|
blockTransformArc(¢er, &p0, &p1);
|
||||||
|
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false);
|
||||||
SK.GetEntity(hr.entity(1))->PointForceTo(center);
|
SK.GetEntity(hr.entity(1))->PointForceTo(center);
|
||||||
SK.GetEntity(hr.entity(2))->PointForceTo(p0);
|
SK.GetEntity(hr.entity(2))->PointForceTo(p0);
|
||||||
SK.GetEntity(hr.entity(3))->PointForceTo(p1);
|
SK.GetEntity(hr.entity(3))->PointForceTo(p1);
|
||||||
@ -477,7 +477,7 @@ public:
|
|||||||
hEntity he = findPoint(p);
|
hEntity he = findPoint(p);
|
||||||
if(he.v != Entity::NO_ENTITY.v) return he;
|
if(he.v != Entity::NO_ENTITY.v) return he;
|
||||||
|
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, /*rememberForUndo=*/false);
|
||||||
he = hr.entity(0);
|
he = hr.entity(0);
|
||||||
SK.GetEntity(he)->PointForceTo(p);
|
SK.GetEntity(he)->PointForceTo(p);
|
||||||
points.emplace(p, he);
|
points.emplace(p, he);
|
||||||
@ -486,7 +486,7 @@ public:
|
|||||||
|
|
||||||
hEntity createLine(Vector p0, Vector p1, uint32_t style, bool constrainHV = false) {
|
hEntity createLine(Vector p0, Vector p1, uint32_t style, bool constrainHV = false) {
|
||||||
if(p0.Equals(p1)) return Entity::NO_ENTITY;
|
if(p0.Equals(p1)) return Entity::NO_ENTITY;
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false);
|
||||||
SK.GetEntity(hr.entity(1))->PointForceTo(p0);
|
SK.GetEntity(hr.entity(1))->PointForceTo(p0);
|
||||||
SK.GetEntity(hr.entity(2))->PointForceTo(p1);
|
SK.GetEntity(hr.entity(2))->PointForceTo(p1);
|
||||||
processPoint(hr.entity(1));
|
processPoint(hr.entity(1));
|
||||||
@ -520,7 +520,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
hEntity createCircle(const Vector &c, double r, uint32_t style) {
|
hEntity createCircle(const Vector &c, double r, uint32_t style) {
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::CIRCLE, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::CIRCLE, /*rememberForUndo=*/false);
|
||||||
SK.GetEntity(hr.entity(1))->PointForceTo(c);
|
SK.GetEntity(hr.entity(1))->PointForceTo(c);
|
||||||
processPoint(hr.entity(1));
|
processPoint(hr.entity(1));
|
||||||
SK.GetEntity(hr.entity(64))->DistanceForceTo(r);
|
SK.GetEntity(hr.entity(64))->DistanceForceTo(r);
|
||||||
@ -548,7 +548,7 @@ public:
|
|||||||
if(data.space != DRW::ModelSpace) return;
|
if(data.space != DRW::ModelSpace) return;
|
||||||
if(addPendingBlockEntity<DRW_Point>(data)) return;
|
if(addPendingBlockEntity<DRW_Point>(data)) return;
|
||||||
|
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, /*rememberForUndo=*/false);
|
||||||
SK.GetEntity(hr.entity(0))->PointForceTo(toVector(data.basePoint));
|
SK.GetEntity(hr.entity(0))->PointForceTo(toVector(data.basePoint));
|
||||||
processPoint(hr.entity(0));
|
processPoint(hr.entity(0));
|
||||||
}
|
}
|
||||||
@ -557,14 +557,14 @@ public:
|
|||||||
if(data.space != DRW::ModelSpace) return;
|
if(data.space != DRW::ModelSpace) return;
|
||||||
if(addPendingBlockEntity<DRW_Line>(data)) return;
|
if(addPendingBlockEntity<DRW_Line>(data)) return;
|
||||||
|
|
||||||
createLine(toVector(data.basePoint), toVector(data.secPoint), styleFor(&data).v, true);
|
createLine(toVector(data.basePoint), toVector(data.secPoint), styleFor(&data).v, /*constrainHV=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addArc(const DRW_Arc &data) override {
|
void addArc(const DRW_Arc &data) override {
|
||||||
if(data.space != DRW::ModelSpace) return;
|
if(data.space != DRW::ModelSpace) return;
|
||||||
if(addPendingBlockEntity<DRW_Arc>(data)) return;
|
if(addPendingBlockEntity<DRW_Arc>(data)) return;
|
||||||
|
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false);
|
||||||
double r = data.radious;
|
double r = data.radious;
|
||||||
double sa = data.staangle;
|
double sa = data.staangle;
|
||||||
double ea = data.endangle;
|
double ea = data.endangle;
|
||||||
@ -625,7 +625,7 @@ public:
|
|||||||
hStyle hs = styleFor(&data);
|
hStyle hs = styleFor(&data);
|
||||||
|
|
||||||
if(EXACT(data.vertlist[i]->bulge == 0.0)) {
|
if(EXACT(data.vertlist[i]->bulge == 0.0)) {
|
||||||
createLine(blockTransform(p0), blockTransform(p1), hs.v, true);
|
createLine(blockTransform(p0), blockTransform(p1), hs.v, /*constrainHV=*/true);
|
||||||
} else {
|
} else {
|
||||||
hRequest hr = createBulge(p0, p1, c0.bulge);
|
hRequest hr = createBulge(p0, p1, c0.bulge);
|
||||||
setStyle(hr, hs);
|
setStyle(hr, hs);
|
||||||
@ -662,7 +662,7 @@ public:
|
|||||||
hStyle hs = styleFor(&data);
|
hStyle hs = styleFor(&data);
|
||||||
|
|
||||||
if(EXACT(bulge == 0.0)) {
|
if(EXACT(bulge == 0.0)) {
|
||||||
createLine(blockTransform(p0), blockTransform(p1), hs.v, true);
|
createLine(blockTransform(p0), blockTransform(p1), hs.v, /*constrainHV=*/true);
|
||||||
} else {
|
} else {
|
||||||
hRequest hr = createBulge(p0, p1, bulge);
|
hRequest hr = createBulge(p0, p1, bulge);
|
||||||
setStyle(hr, hs);
|
setStyle(hr, hs);
|
||||||
@ -675,7 +675,7 @@ public:
|
|||||||
if(data->degree != 3) return;
|
if(data->degree != 3) return;
|
||||||
if(addPendingBlockEntity<DRW_Spline>(*data)) return;
|
if(addPendingBlockEntity<DRW_Spline>(*data)) return;
|
||||||
|
|
||||||
hRequest hr = SS.GW.AddRequest(Request::Type::CUBIC, false);
|
hRequest hr = SS.GW.AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false);
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 4; i++) {
|
||||||
SK.GetEntity(hr.entity(i + 1))->PointForceTo(toVector(*data->controllist[i]));
|
SK.GetEntity(hr.entity(i + 1))->PointForceTo(toVector(*data->controllist[i]));
|
||||||
processPoint(hr.entity(i + 1));
|
processPoint(hr.entity(i + 1));
|
||||||
@ -737,7 +737,7 @@ public:
|
|||||||
}
|
}
|
||||||
c.comment = data.text;
|
c.comment = data.text;
|
||||||
c.disp.style = styleFor(&data);
|
c.disp.style = styleFor(&data);
|
||||||
Constraint::AddConstraint(&c, false);
|
Constraint::AddConstraint(&c, /*rememberForUndo=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addDimAlign(const DRW_DimAligned *data) override {
|
void addDimAlign(const DRW_DimAligned *data) override {
|
||||||
@ -767,9 +767,9 @@ public:
|
|||||||
if(data->space != DRW::ModelSpace) return;
|
if(data->space != DRW::ModelSpace) return;
|
||||||
if(addPendingBlockEntity<DRW_DimLinear>(*data)) return;
|
if(addPendingBlockEntity<DRW_DimLinear>(*data)) return;
|
||||||
|
|
||||||
Vector p0 = toVector(data->getDef1Point(), false);
|
Vector p0 = toVector(data->getDef1Point(), /*transform=*/false);
|
||||||
Vector p1 = toVector(data->getDef2Point(), false);
|
Vector p1 = toVector(data->getDef2Point(), /*transform=*/false);
|
||||||
Vector p2 = toVector(data->getTextPoint(), false);
|
Vector p2 = toVector(data->getTextPoint(), /*transform=*/false);
|
||||||
|
|
||||||
double angle = data->getAngle() * PI / 180.0;
|
double angle = data->getAngle() * PI / 180.0;
|
||||||
Vector dir = Vector::From(cos(angle), sin(angle), 0.0);
|
Vector dir = Vector::From(cos(angle), sin(angle), 0.0);
|
||||||
@ -909,7 +909,7 @@ void ImportDxf(const std::string &filename) {
|
|||||||
dxfRW dxf(filename.c_str());
|
dxfRW dxf(filename.c_str());
|
||||||
DxfReadInterface interface;
|
DxfReadInterface interface;
|
||||||
interface.clearBlockTransform();
|
interface.clearBlockTransform();
|
||||||
if(!dxf.read(&interface, false)) {
|
if(!dxf.read(&interface, /*ext=*/false)) {
|
||||||
Error("Corrupted DXF file!");
|
Error("Corrupted DXF file!");
|
||||||
}
|
}
|
||||||
if(interface.unknownEntities > 0) {
|
if(interface.unknownEntities > 0) {
|
||||||
@ -923,7 +923,7 @@ void ImportDwg(const std::string &filename) {
|
|||||||
dwgR dwg(filename.c_str());
|
dwgR dwg(filename.c_str());
|
||||||
DxfReadInterface interface;
|
DxfReadInterface interface;
|
||||||
interface.clearBlockTransform();
|
interface.clearBlockTransform();
|
||||||
if(!dwg.read(&interface, false)) {
|
if(!dwg.read(&interface, /*ext=*/false)) {
|
||||||
Error("Corrupted DWG file!");
|
Error("Corrupted DWG file!");
|
||||||
}
|
}
|
||||||
if(interface.unknownEntities > 0) {
|
if(interface.unknownEntities > 0) {
|
||||||
|
@ -209,7 +209,7 @@ default: dbp("bad constraint type %d", sc->type); return;
|
|||||||
|
|
||||||
// Now we're finally ready to solve!
|
// Now we're finally ready to solve!
|
||||||
bool andFindBad = ssys->calculateFaileds ? true : false;
|
bool andFindBad = ssys->calculateFaileds ? true : false;
|
||||||
SolveResult how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, false);
|
SolveResult how = SYS.Solve(&g, &(ssys->dof), &bad, andFindBad, /*andFindFree=*/false);
|
||||||
|
|
||||||
switch(how) {
|
switch(how) {
|
||||||
case SolveResult::OKAY:
|
case SolveResult::OKAY:
|
||||||
|
@ -86,14 +86,14 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
|
|||||||
SKdNode *root = SKdNode::From(&m);
|
SKdNode *root = SKdNode::From(&m);
|
||||||
root->SnapToMesh(&m);
|
root->SnapToMesh(&m);
|
||||||
root->MakeCertainEdgesInto(sel, EdgeKind::NAKED_OR_SELF_INTER,
|
root->MakeCertainEdgesInto(sel, EdgeKind::NAKED_OR_SELF_INTER,
|
||||||
false, NULL, NULL);
|
/*coplanarIsInter=*/false, NULL, NULL);
|
||||||
|
|
||||||
m.Clear();
|
m.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMesh::MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, EdgeKind type) {
|
void SMesh::MakeCertainEdgesAndOutlinesInto(SEdgeList *sel, SOutlineList *sol, EdgeKind type) {
|
||||||
SKdNode *root = SKdNode::From(this);
|
SKdNode *root = SKdNode::From(this);
|
||||||
root->MakeCertainEdgesInto(sel, type, false, NULL, NULL);
|
root->MakeCertainEdgesInto(sel, type, /*coplanarIsInter=*/false, NULL, NULL);
|
||||||
root->MakeOutlinesInto(sol);
|
root->MakeOutlinesInto(sol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
|
|||||||
hRequest hr;
|
hRequest hr;
|
||||||
Entity *e;
|
Entity *e;
|
||||||
if(isLine) {
|
if(isLine) {
|
||||||
hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, false),
|
hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false),
|
||||||
e = SK.GetEntity(hr.entity(0));
|
e = SK.GetEntity(hr.entity(0));
|
||||||
SK.GetEntity(e->point[0])->PointForceTo(PointAt(t));
|
SK.GetEntity(e->point[0])->PointForceTo(PointAt(t));
|
||||||
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
|
SK.GetEntity(e->point[1])->PointForceTo(PointAt(1));
|
||||||
@ -179,9 +179,9 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
|
|||||||
}
|
}
|
||||||
Constraint::Constrain(Constraint::Type::ARC_LINE_TANGENT,
|
Constraint::Constrain(Constraint::Type::ARC_LINE_TANGENT,
|
||||||
Entity::NO_ENTITY, Entity::NO_ENTITY,
|
Entity::NO_ENTITY, Entity::NO_ENTITY,
|
||||||
arc, e->h, arcFinish, false);
|
arc, e->h, /*other=*/arcFinish, /*other2=*/false);
|
||||||
} else {
|
} else {
|
||||||
hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, false),
|
hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false),
|
||||||
e = SK.GetEntity(hr.entity(0));
|
e = SK.GetEntity(hr.entity(0));
|
||||||
SK.GetEntity(e->point[0])->PointForceTo(p0);
|
SK.GetEntity(e->point[0])->PointForceTo(p0);
|
||||||
if(dtheta > 0) {
|
if(dtheta > 0) {
|
||||||
@ -198,7 +198,7 @@ hRequest GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
|
|||||||
// so there's no need for more.
|
// so there's no need for more.
|
||||||
Constraint::Constrain(Constraint::Type::CURVE_CURVE_TANGENT,
|
Constraint::Constrain(Constraint::Type::CURVE_CURVE_TANGENT,
|
||||||
Entity::NO_ENTITY, Entity::NO_ENTITY,
|
Entity::NO_ENTITY, Entity::NO_ENTITY,
|
||||||
arc, e->h, arcFinish, (dtheta < 0));
|
arc, e->h, /*other=*/arcFinish, /*other2=*/(dtheta < 0));
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
@ -389,7 +389,7 @@ void GraphicsWindow::MakeTangentArc() {
|
|||||||
|
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
hRequest harc = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
|
hRequest harc = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false);
|
||||||
Entity *earc = SK.GetEntity(harc.entity(0));
|
Entity *earc = SK.GetEntity(harc.entity(0));
|
||||||
hEntity hearc = earc->h;
|
hEntity hearc = earc->h;
|
||||||
|
|
||||||
@ -400,9 +400,9 @@ void GraphicsWindow::MakeTangentArc() {
|
|||||||
earc = NULL;
|
earc = NULL;
|
||||||
|
|
||||||
pc[0].CreateRequestTrimmedTo(t[0], !SS.tangentArcDeleteOld,
|
pc[0].CreateRequestTrimmedTo(t[0], !SS.tangentArcDeleteOld,
|
||||||
hent[0], hearc, (b == 1));
|
hent[0], hearc, /*arcFinish=*/(b == 1));
|
||||||
pc[1].CreateRequestTrimmedTo(t[1], !SS.tangentArcDeleteOld,
|
pc[1].CreateRequestTrimmedTo(t[1], !SS.tangentArcDeleteOld,
|
||||||
hent[1], hearc, (a == 1));
|
hent[1], hearc, /*arcFinish=*/(a == 1));
|
||||||
|
|
||||||
// Now either make the original entities construction, or delete them
|
// Now either make the original entities construction, or delete them
|
||||||
// entirely, according to user preference.
|
// entirely, according to user preference.
|
||||||
@ -432,8 +432,8 @@ hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) {
|
|||||||
p1 = SK.GetEntity(hep1)->PointGetNum();
|
p1 = SK.GetEntity(hep1)->PointGetNum();
|
||||||
|
|
||||||
// Add the two line segments this one gets split into.
|
// Add the two line segments this one gets split into.
|
||||||
hRequest r0i = AddRequest(Request::Type::LINE_SEGMENT, false),
|
hRequest r0i = AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false),
|
||||||
ri1 = AddRequest(Request::Type::LINE_SEGMENT, false);
|
ri1 = AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false);
|
||||||
// Don't get entities till after adding, realloc issues
|
// Don't get entities till after adding, realloc issues
|
||||||
|
|
||||||
Entity *e0i = SK.GetEntity(r0i.entity(0)),
|
Entity *e0i = SK.GetEntity(r0i.entity(0)),
|
||||||
@ -457,7 +457,7 @@ hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
|
|||||||
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
|
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
|
||||||
|
|
||||||
circle = NULL; // shortly invalid!
|
circle = NULL; // shortly invalid!
|
||||||
hRequest hr = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
|
hRequest hr = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false);
|
||||||
|
|
||||||
Entity *arc = SK.GetEntity(hr.entity(0));
|
Entity *arc = SK.GetEntity(hr.entity(0));
|
||||||
|
|
||||||
@ -477,8 +477,8 @@ hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) {
|
|||||||
finish = SK.GetEntity(hf)->PointGetNum();
|
finish = SK.GetEntity(hf)->PointGetNum();
|
||||||
|
|
||||||
circle = NULL; // shortly invalid!
|
circle = NULL; // shortly invalid!
|
||||||
hRequest hr0 = AddRequest(Request::Type::ARC_OF_CIRCLE, false),
|
hRequest hr0 = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false),
|
||||||
hr1 = AddRequest(Request::Type::ARC_OF_CIRCLE, false);
|
hr1 = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false);
|
||||||
|
|
||||||
Entity *arc0 = SK.GetEntity(hr0.entity(0)),
|
Entity *arc0 = SK.GetEntity(hr0.entity(0)),
|
||||||
*arc1 = SK.GetEntity(hr1.entity(0));
|
*arc1 = SK.GetEntity(hr1.entity(0));
|
||||||
@ -518,15 +518,15 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
|
|||||||
SBezier *sb = &(sbl.l.elem[i]);
|
SBezier *sb = &(sbl.l.elem[i]);
|
||||||
ssassert(sb->deg == 3, "Expected a cubic bezier");
|
ssassert(sb->deg == 3, "Expected a cubic bezier");
|
||||||
|
|
||||||
sb->ClosestPointTo(pinter, &t, false);
|
sb->ClosestPointTo(pinter, &t, /*mustConverge=*/false);
|
||||||
if(pinter.Equals(sb->PointAt(t))) {
|
if(pinter.Equals(sb->PointAt(t))) {
|
||||||
// Split that segment at the intersection.
|
// Split that segment at the intersection.
|
||||||
SBezier b0i, bi1, b01 = *sb;
|
SBezier b0i, bi1, b01 = *sb;
|
||||||
b01.SplitAt(t, &b0i, &bi1);
|
b01.SplitAt(t, &b0i, &bi1);
|
||||||
|
|
||||||
// Add the two cubic segments this one gets split into.
|
// Add the two cubic segments this one gets split into.
|
||||||
hRequest r0i = AddRequest(Request::Type::CUBIC, false),
|
hRequest r0i = AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false),
|
||||||
ri1 = AddRequest(Request::Type::CUBIC, false);
|
ri1 = AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false);
|
||||||
// Don't get entities till after adding, realloc issues
|
// Don't get entities till after adding, realloc issues
|
||||||
|
|
||||||
Entity *e0i = SK.GetEntity(r0i.entity(0)),
|
Entity *e0i = SK.GetEntity(r0i.entity(0)),
|
||||||
@ -544,7 +544,7 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
|
|||||||
hep1n = ei1->point[3];
|
hep1n = ei1->point[3];
|
||||||
hepin = e0i->point[3];
|
hepin = e0i->point[3];
|
||||||
} else {
|
} else {
|
||||||
hRequest r = AddRequest(Request::Type::CUBIC, false);
|
hRequest r = AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false);
|
||||||
Entity *e = SK.GetEntity(r.entity(0));
|
Entity *e = SK.GetEntity(r.entity(0));
|
||||||
|
|
||||||
for(j = 0; j <= 3; j++) {
|
for(j = 0; j <= 3; j++) {
|
||||||
|
@ -223,7 +223,7 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown,
|
|||||||
if(hover.entity.v) {
|
if(hover.entity.v) {
|
||||||
// Avoid accidentally selecting workplanes when
|
// Avoid accidentally selecting workplanes when
|
||||||
// starting drags.
|
// starting drags.
|
||||||
MakeUnselected(hover.entity, false);
|
MakeUnselected(hover.entity, /*coincidentPointTrick=*/false);
|
||||||
hover.Clear();
|
hover.Clear();
|
||||||
}
|
}
|
||||||
pending.operation = Pending::DRAGGING_MARQUEE;
|
pending.operation = Pending::DRAGGING_MARQUEE;
|
||||||
@ -644,7 +644,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||||||
|
|
||||||
case ContextCommand::UNSELECT_HOVERED:
|
case ContextCommand::UNSELECT_HOVERED:
|
||||||
if(!hover.IsEmpty()) {
|
if(!hover.IsEmpty()) {
|
||||||
MakeUnselected(&hover, true);
|
MakeUnselected(&hover, /*coincidentPointTrick=*/true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -825,7 +825,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hRequest GraphicsWindow::AddRequest(Request::Type type) {
|
hRequest GraphicsWindow::AddRequest(Request::Type type) {
|
||||||
return AddRequest(type, true);
|
return AddRequest(type, /*rememberForUndo=*/true);
|
||||||
}
|
}
|
||||||
hRequest GraphicsWindow::AddRequest(Request::Type type, bool rememberForUndo) {
|
hRequest GraphicsWindow::AddRequest(Request::Type type, bool rememberForUndo) {
|
||||||
if(rememberForUndo) SS.UndoRemember();
|
if(rememberForUndo) SS.UndoRemember();
|
||||||
@ -889,7 +889,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the hover is up to date.
|
// Make sure the hover is up to date.
|
||||||
MouseMoved(mx, my, false, false, false, false, false);
|
MouseMoved(mx, my, /*leftDown=*/false, /*middleDown=*/false, /*rightDown=*/false,
|
||||||
|
/*shiftDown=*/false, /*ctrlDown=*/false);
|
||||||
orig.mouse.x = mx;
|
orig.mouse.x = mx;
|
||||||
orig.mouse.y = my;
|
orig.mouse.y = my;
|
||||||
orig.mouseOnButtonDown = orig.mouse;
|
orig.mouseOnButtonDown = orig.mouse;
|
||||||
@ -938,7 +939,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
|||||||
int i;
|
int i;
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
lns[i] = AddRequest(Request::Type::LINE_SEGMENT, false);
|
lns[i] = AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false);
|
||||||
}
|
}
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
Constraint::ConstrainCoincident(
|
Constraint::ConstrainCoincident(
|
||||||
|
@ -1041,13 +1041,13 @@ static bool OpenSaveFile(bool isOpen, std::string *filename, const std::string &
|
|||||||
bool SolveSpace::GetOpenFile(std::string *filename, const std::string &defExtension,
|
bool SolveSpace::GetOpenFile(std::string *filename, const std::string &defExtension,
|
||||||
const FileFilter filters[])
|
const FileFilter filters[])
|
||||||
{
|
{
|
||||||
return OpenSaveFile(true, filename, defExtension, filters);
|
return OpenSaveFile(/*isOpen=*/true, filename, defExtension, filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpace::GetSaveFile(std::string *filename, const std::string &defExtension,
|
bool SolveSpace::GetSaveFile(std::string *filename, const std::string &defExtension,
|
||||||
const FileFilter filters[])
|
const FileFilter filters[])
|
||||||
{
|
{
|
||||||
return OpenSaveFile(false, filename, defExtension, filters);
|
return OpenSaveFile(/*isOpen=*/false, filename, defExtension, filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogChoice SolveSpace::SaveFileYesNoCancel()
|
DialogChoice SolveSpace::SaveFileYesNoCancel()
|
||||||
|
@ -335,12 +335,12 @@ void SolveSpaceUI::AfterNewFile() {
|
|||||||
// roughly in the window, since that sets the mesh tolerance. Consider
|
// roughly in the window, since that sets the mesh tolerance. Consider
|
||||||
// invisible entities, so we still get something reasonable if the only
|
// invisible entities, so we still get something reasonable if the only
|
||||||
// thing visible is the not-yet-generated surfaces.
|
// thing visible is the not-yet-generated surfaces.
|
||||||
GW.ZoomToFit(true);
|
GW.ZoomToFit(/*includingInvisibles=*/true);
|
||||||
|
|
||||||
GenerateAll(Generate::ALL);
|
GenerateAll(Generate::ALL);
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
// Then zoom to fit again, to fit the triangles
|
// Then zoom to fit again, to fit the triangles
|
||||||
GW.ZoomToFit(false);
|
GW.ZoomToFit(/*includingInvisibles=*/false);
|
||||||
|
|
||||||
// Create all the default styles; they'll get created on the fly anyways,
|
// Create all the default styles; they'll get created on the fly anyways,
|
||||||
// but can't hurt to do it now.
|
// but can't hurt to do it now.
|
||||||
@ -412,7 +412,7 @@ bool SolveSpaceUI::OkayToStartNewFile() {
|
|||||||
|
|
||||||
switch(SaveFileYesNoCancel()) {
|
switch(SaveFileYesNoCancel()) {
|
||||||
case DIALOG_YES:
|
case DIALOG_YES:
|
||||||
return GetFilenameAndSave(false);
|
return GetFilenameAndSave(/*saveAs=*/false);
|
||||||
|
|
||||||
case DIALOG_NO:
|
case DIALOG_NO:
|
||||||
return true;
|
return true;
|
||||||
@ -464,11 +464,11 @@ void SolveSpaceUI::MenuFile(Command id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Command::SAVE:
|
case Command::SAVE:
|
||||||
SS.GetFilenameAndSave(false);
|
SS.GetFilenameAndSave(/*saveAs=*/false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SAVE_AS:
|
case Command::SAVE_AS:
|
||||||
SS.GetFilenameAndSave(true);
|
SS.GetFilenameAndSave(/*saveAs=*/true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::EXPORT_PNG: {
|
case Command::EXPORT_PNG: {
|
||||||
@ -496,7 +496,7 @@ void SolveSpaceUI::MenuFile(Command id) {
|
|||||||
"text window.");
|
"text window.");
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.ExportViewOrWireframeTo(exportFile, false);
|
SS.ExportViewOrWireframeTo(exportFile, /*exportWireframe*/false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,7 +506,7 @@ void SolveSpaceUI::MenuFile(Command id) {
|
|||||||
Vector3dFileFilter)) break;
|
Vector3dFileFilter)) break;
|
||||||
CnfFreezeString(Extension(exportFile), "WireframeExportFormat");
|
CnfFreezeString(Extension(exportFile), "WireframeExportFormat");
|
||||||
|
|
||||||
SS.ExportViewOrWireframeTo(exportFile, true);
|
SS.ExportViewOrWireframeTo(exportFile, /*exportWireframe*/true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +610,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
|||||||
SKdNode *root = SKdNode::From(m);
|
SKdNode *root = SKdNode::From(m);
|
||||||
bool inters, leaks;
|
bool inters, leaks;
|
||||||
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
||||||
EdgeKind::NAKED_OR_SELF_INTER, true, &inters, &leaks);
|
EdgeKind::NAKED_OR_SELF_INTER, /*coplanarIsInter=*/true, &inters, &leaks);
|
||||||
|
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
|
|
||||||
@ -641,7 +641,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
|||||||
SKdNode *root = SKdNode::From(m);
|
SKdNode *root = SKdNode::From(m);
|
||||||
bool inters, leaks;
|
bool inters, leaks;
|
||||||
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
root->MakeCertainEdgesInto(&(SS.nakedEdges),
|
||||||
EdgeKind::SELF_INTER, false, &inters, &leaks);
|
EdgeKind::SELF_INTER, /*coplanarIsInter=*/false, &inters, &leaks);
|
||||||
|
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
|
|
||||||
@ -734,7 +734,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
|||||||
SEdgeList sel = {};
|
SEdgeList sel = {};
|
||||||
g->polyLoops.MakeEdgesInto(&sel);
|
g->polyLoops.MakeEdgesInto(&sel);
|
||||||
SPolygon sp = {};
|
SPolygon sp = {};
|
||||||
sel.AssemblePolygon(&sp, NULL, true);
|
sel.AssemblePolygon(&sp, NULL, /*keepDir=*/true);
|
||||||
sp.normal = sp.ComputeNormal();
|
sp.normal = sp.ComputeNormal();
|
||||||
sp.FixContourDirections();
|
sp.FixContourDirections();
|
||||||
double area = sp.SignedArea();
|
double area = sp.SignedArea();
|
||||||
|
@ -853,7 +853,7 @@ public:
|
|||||||
void ExportMeshAsObjTo(FILE *f, SMesh *sm);
|
void ExportMeshAsObjTo(FILE *f, SMesh *sm);
|
||||||
void ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
void ExportMeshAsThreeJsTo(FILE *f, const std::string &filename,
|
||||||
SMesh *sm, SEdgeList *sel);
|
SMesh *sm, SEdgeList *sel);
|
||||||
void ExportViewOrWireframeTo(const std::string &filename, bool wireframe);
|
void ExportViewOrWireframeTo(const std::string &filename, bool exportWireframe);
|
||||||
void ExportSectionTo(const std::string &filename);
|
void ExportSectionTo(const std::string &filename);
|
||||||
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl,
|
||||||
VectorFileWriter *out);
|
VectorFileWriter *out);
|
||||||
|
@ -53,9 +53,11 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
|
|||||||
|
|
||||||
// Find all the intersections with the two passed shells
|
// Find all the intersections with the two passed shells
|
||||||
if(agnstA)
|
if(agnstA)
|
||||||
agnstA->AllPointsIntersecting(prev.p, p->p, &il, true, false, true);
|
agnstA->AllPointsIntersecting(prev.p, p->p, &il,
|
||||||
|
/*asSegment=*/true, /*trimmed=*/false, /*inclTangent=*/true);
|
||||||
if(agnstB)
|
if(agnstB)
|
||||||
agnstB->AllPointsIntersecting(prev.p, p->p, &il, true, false, true);
|
agnstB->AllPointsIntersecting(prev.p, p->p, &il,
|
||||||
|
/*asSegment=*/true, /*trimmed=*/false, /*inclTangent=*/true);
|
||||||
|
|
||||||
if(il.n > 0) {
|
if(il.n > 0) {
|
||||||
// The intersections were generated by intersecting the pwl
|
// The intersections were generated by intersecting the pwl
|
||||||
@ -76,7 +78,7 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Point2d puv;
|
Point2d puv;
|
||||||
(pi->srf)->ClosestPointTo(pi->p, &puv, false);
|
(pi->srf)->ClosestPointTo(pi->p, &puv, /*mustConverge=*/false);
|
||||||
|
|
||||||
// Split the edge if the intersection lies within the surface's
|
// Split the edge if the intersection lies within the surface's
|
||||||
// trim curves, or within the chord tol of the trim curve; want
|
// trim curves, or within the chord tol of the trim curve; want
|
||||||
@ -359,7 +361,7 @@ void SSurface::EdgeNormalsWithinSurface(Point2d auv, Point2d buv,
|
|||||||
SCurve *sc = shell->curve.FindById(hc);
|
SCurve *sc = shell->curve.FindById(hc);
|
||||||
if(sc->isExact && sc->exact.deg != 1) {
|
if(sc->isExact && sc->exact.deg != 1) {
|
||||||
double t;
|
double t;
|
||||||
sc->exact.ClosestPointTo(*pt, &t, false);
|
sc->exact.ClosestPointTo(*pt, &t, /*mustConverge=*/false);
|
||||||
*pt = sc->exact.PointAt(t);
|
*pt = sc->exact.PointAt(t);
|
||||||
ClosestPointTo(*pt, &muv);
|
ClosestPointTo(*pt, &muv);
|
||||||
} else if(!sc->isExact) {
|
} else if(!sc->isExact) {
|
||||||
@ -584,11 +586,11 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
|||||||
final.CullExtraneousEdges();
|
final.CullExtraneousEdges();
|
||||||
|
|
||||||
// Use our reassembled edges to trim the new surface.
|
// Use our reassembled edges to trim the new surface.
|
||||||
ret.TrimFromEdgeList(&final, true);
|
ret.TrimFromEdgeList(&final, /*asUv=*/true);
|
||||||
|
|
||||||
SPolygon poly = {};
|
SPolygon poly = {};
|
||||||
final.l.ClearTags();
|
final.l.ClearTags();
|
||||||
if(!final.AssemblePolygon(&poly, NULL, true)) {
|
if(!final.AssemblePolygon(&poly, NULL, /*keepDir=*/true)) {
|
||||||
into->booleanFailed = true;
|
into->booleanFailed = true;
|
||||||
dbp("failed: I=%d, avoid=%d", I, choosing.l.n);
|
dbp("failed: I=%d, avoid=%d", I, choosing.l.n);
|
||||||
DEBUGEDGELIST(&final, &ret);
|
DEBUGEDGELIST(&final, &ret);
|
||||||
@ -679,7 +681,7 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
|
|||||||
for(i = 0; i < 2; i++) {
|
for(i = 0; i < 2; i++) {
|
||||||
ab = (i == 0) ? a : b;
|
ab = (i == 0) ? a : b;
|
||||||
for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) {
|
for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) {
|
||||||
sn = SSurface::FromTransformationOf(s, t, q, 1.0, true);
|
sn = SSurface::FromTransformationOf(s, t, q, 1.0, /*includingTrims=*/true);
|
||||||
// All the trim curve IDs get rewritten; we know the new handles
|
// All the trim curve IDs get rewritten; we know the new handles
|
||||||
// to the curves since we recorded them in the previous step.
|
// to the curves since we recorded them in the previous step.
|
||||||
STrimBy *stb;
|
STrimBy *stb;
|
||||||
@ -704,8 +706,8 @@ void SShell::MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type) {
|
|||||||
// Copy over all the original curves, splitting them so that a
|
// Copy over all the original curves, splitting them so that a
|
||||||
// piecwise linear segment never crosses a surface from the other
|
// piecwise linear segment never crosses a surface from the other
|
||||||
// shell.
|
// shell.
|
||||||
a->CopyCurvesSplitAgainst(true, b, this);
|
a->CopyCurvesSplitAgainst(/*opA=*/true, b, this);
|
||||||
b->CopyCurvesSplitAgainst(false, a, this);
|
b->CopyCurvesSplitAgainst(/*opA=*/false, a, this);
|
||||||
|
|
||||||
// Generate the intersection curves for each surface in A against all
|
// Generate the intersection curves for each surface in A against all
|
||||||
// the surfaces in B (which is all of the intersection curves).
|
// the surfaces in B (which is all of the intersection curves).
|
||||||
@ -833,12 +835,12 @@ double SBspUv::ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b,
|
|||||||
return pt.Dot(n) - d;
|
return pt.Dot(n) - d;
|
||||||
}
|
}
|
||||||
|
|
||||||
double SBspUv::ScaledDistanceToLine(Point2d pt, Point2d a, Point2d b, bool seg,
|
double SBspUv::ScaledDistanceToLine(Point2d pt, Point2d a, Point2d b, bool asSegment,
|
||||||
SSurface *srf) const
|
SSurface *srf) const
|
||||||
{
|
{
|
||||||
ScalePoints(&pt, &a, &b, srf);
|
ScalePoints(&pt, &a, &b, srf);
|
||||||
|
|
||||||
return pt.DistanceToLine(a, b, seg);
|
return pt.DistanceToLine(a, b, asSegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
SBspUv *SBspUv::InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf) {
|
SBspUv *SBspUv::InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf) {
|
||||||
@ -905,8 +907,8 @@ SBspUv::Class SBspUv::ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const
|
|||||||
const SBspUv *f = this;
|
const SBspUv *f = this;
|
||||||
while(f) {
|
while(f) {
|
||||||
Point2d ba = (f->b).Minus(f->a);
|
Point2d ba = (f->b).Minus(f->a);
|
||||||
if(ScaledDistanceToLine(p, f->a, ba, true, srf) < LENGTH_EPS) {
|
if(ScaledDistanceToLine(p, f->a, ba, /*asSegment=*/true, srf) < LENGTH_EPS) {
|
||||||
if(ScaledDistanceToLine(eb, f->a, ba, false, srf) < LENGTH_EPS){
|
if(ScaledDistanceToLine(eb, f->a, ba, /*asSegment=*/false, srf) < LENGTH_EPS){
|
||||||
if(ba.Dot(eb.Minus(p)) > 0) {
|
if(ba.Dot(eb.Minus(p)) > 0) {
|
||||||
return Class::EDGE_PARALLEL;
|
return Class::EDGE_PARALLEL;
|
||||||
} else {
|
} else {
|
||||||
@ -950,7 +952,7 @@ double SBspUv::MinimumDistanceToEdge(Point2d p, SSurface *srf) const {
|
|||||||
|
|
||||||
Point2d as = a, bs = b;
|
Point2d as = a, bs = b;
|
||||||
ScalePoints(&p, &as, &bs, srf);
|
ScalePoints(&p, &as, &bs, srf);
|
||||||
double d = p.DistanceToLine(as, bs.Minus(as), true);
|
double d = p.DistanceToLine(as, bs.Minus(as), /*asSegment=*/true);
|
||||||
|
|
||||||
return min(d, min(dn, dp));
|
return min(d, min(dn, dp));
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ void SShell::MergeCoincidentSurfaces() {
|
|||||||
for(j = i + 1; j < surface.n; j++) {
|
for(j = i + 1; j < surface.n; j++) {
|
||||||
sj = &(surface.elem[j]);
|
sj = &(surface.elem[j]);
|
||||||
if(sj->tag) continue;
|
if(sj->tag) continue;
|
||||||
if(!sj->CoincidentWith(si, true)) continue;
|
if(!sj->CoincidentWith(si, /*sameNormal=*/true)) continue;
|
||||||
if(!sj->color.Equals(si->color)) continue;
|
if(!sj->color.Equals(si->color)) continue;
|
||||||
// But we do merge surfaces with different face entities, since
|
// But we do merge surfaces with different face entities, since
|
||||||
// otherwise we'd hardly ever merge anything.
|
// otherwise we'd hardly ever merge anything.
|
||||||
@ -72,7 +72,7 @@ void SShell::MergeCoincidentSurfaces() {
|
|||||||
if(merged) {
|
if(merged) {
|
||||||
sel.CullExtraneousEdges();
|
sel.CullExtraneousEdges();
|
||||||
si->trim.Clear();
|
si->trim.Clear();
|
||||||
si->TrimFromEdgeList(&sel, false);
|
si->TrimFromEdgeList(&sel, /*asUv=*/false);
|
||||||
|
|
||||||
// And we must choose control points such that all the trims lie
|
// And we must choose control points such that all the trims lie
|
||||||
// with u and v in [0, 1], so that the bbox tests work.
|
// with u and v in [0, 1], so that the bbox tests work.
|
||||||
|
@ -130,7 +130,7 @@ Vector SBezier::TangentAt(double t) const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBezier::ClosestPointTo(Vector p, double *t, bool converge) const {
|
void SBezier::ClosestPointTo(Vector p, double *t, bool mustConverge) const {
|
||||||
int i;
|
int i;
|
||||||
double minDist = VERY_POSITIVE;
|
double minDist = VERY_POSITIVE;
|
||||||
*t = 0;
|
*t = 0;
|
||||||
@ -147,7 +147,7 @@ void SBezier::ClosestPointTo(Vector p, double *t, bool converge) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector p0;
|
Vector p0;
|
||||||
for(i = 0; i < (converge ? 15 : 5); i++) {
|
for(i = 0; i < (mustConverge ? 15 : 5); i++) {
|
||||||
p0 = PointAt(*t);
|
p0 = PointAt(*t);
|
||||||
if(p0.Equals(p, RATPOLY_EPS)) {
|
if(p0.Equals(p, RATPOLY_EPS)) {
|
||||||
return;
|
return;
|
||||||
@ -157,15 +157,15 @@ void SBezier::ClosestPointTo(Vector p, double *t, bool converge) const {
|
|||||||
Vector pc = p.ClosestPointOnLine(p0, dp);
|
Vector pc = p.ClosestPointOnLine(p0, dp);
|
||||||
*t += (pc.Minus(p0)).DivPivoting(dp);
|
*t += (pc.Minus(p0)).DivPivoting(dp);
|
||||||
}
|
}
|
||||||
if(converge) {
|
if(mustConverge) {
|
||||||
dbp("didn't converge (closest point on bezier curve)");
|
dbp("didn't converge (closest point on bezier curve)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SBezier::PointOnThisAndCurve(const SBezier *sbb, Vector *p) const {
|
bool SBezier::PointOnThisAndCurve(const SBezier *sbb, Vector *p) const {
|
||||||
double ta, tb;
|
double ta, tb;
|
||||||
this->ClosestPointTo(*p, &ta, false);
|
this->ClosestPointTo(*p, &ta, /*mustConverge=*/false);
|
||||||
sbb ->ClosestPointTo(*p, &tb, false);
|
sbb ->ClosestPointTo(*p, &tb, /*mustConverge=*/false);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 20; i++) {
|
for(i = 0; i < 20; i++) {
|
||||||
@ -387,11 +387,11 @@ Vector SSurface::NormalAt(double u, double v) const {
|
|||||||
return tu.Cross(tv);
|
return tu.Cross(tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSurface::ClosestPointTo(Vector p, Point2d *puv, bool converge) {
|
void SSurface::ClosestPointTo(Vector p, Point2d *puv, bool mustConverge) {
|
||||||
ClosestPointTo(p, &(puv->x), &(puv->y), converge);
|
ClosestPointTo(p, &(puv->x), &(puv->y), mustConverge);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool converge) {
|
void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool mustConverge) {
|
||||||
// A few special cases first; when control points are coincident the
|
// A few special cases first; when control points are coincident the
|
||||||
// derivative goes to zero at the conrol points, and would result in
|
// derivative goes to zero at the conrol points, and would result in
|
||||||
// nonconvergence. We avoid that here, and also guarantee a consistent
|
// nonconvergence. We avoid that here, and also guarantee a consistent
|
||||||
@ -418,9 +418,9 @@ void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool converge) {
|
|||||||
// good if we're working our way along a curve or something else where
|
// good if we're working our way along a curve or something else where
|
||||||
// we project successive points that are close to each other; something
|
// we project successive points that are close to each other; something
|
||||||
// like a 20% speedup empirically.
|
// like a 20% speedup empirically.
|
||||||
if(converge) {
|
if(mustConverge) {
|
||||||
double ut = cached.x, vt = cached.y;
|
double ut = cached.x, vt = cached.y;
|
||||||
if(ClosestPointNewton(p, &ut, &vt, converge)) {
|
if(ClosestPointNewton(p, &ut, &vt, mustConverge)) {
|
||||||
cached.x = *u = ut;
|
cached.x = *u = ut;
|
||||||
cached.y = *v = vt;
|
cached.y = *v = vt;
|
||||||
return;
|
return;
|
||||||
@ -445,7 +445,7 @@ void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool converge) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ClosestPointNewton(p, u, v, converge)) {
|
if(ClosestPointNewton(p, u, v, mustConverge)) {
|
||||||
cached.x = *u;
|
cached.x = *u;
|
||||||
cached.y = *v;
|
cached.y = *v;
|
||||||
return;
|
return;
|
||||||
@ -457,13 +457,13 @@ void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool converge) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool converge) const
|
bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool mustConverge) const
|
||||||
{
|
{
|
||||||
// Initial guess is in u, v; refine by Newton iteration.
|
// Initial guess is in u, v; refine by Newton iteration.
|
||||||
Vector p0 = Vector::From(0, 0, 0);
|
Vector p0 = Vector::From(0, 0, 0);
|
||||||
for(int i = 0; i < (converge ? 25 : 5); i++) {
|
for(int i = 0; i < (mustConverge ? 25 : 5); i++) {
|
||||||
p0 = PointAt(*u, *v);
|
p0 = PointAt(*u, *v);
|
||||||
if(converge) {
|
if(mustConverge) {
|
||||||
if(p0.Equals(p, RATPOLY_EPS)) {
|
if(p0.Equals(p, RATPOLY_EPS)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -481,7 +481,7 @@ bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool converge)
|
|||||||
*v += dv / (tv.MagSquared());
|
*v += dv / (tv.MagSquared());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(converge) {
|
if(mustConverge) {
|
||||||
dbp("didn't converge");
|
dbp("didn't converge");
|
||||||
dbp("have %.3f %.3f %.3f", CO(p0));
|
dbp("have %.3f %.3f %.3f", CO(p0));
|
||||||
dbp("want %.3f %.3f %.3f", CO(p));
|
dbp("want %.3f %.3f %.3f", CO(p));
|
||||||
@ -525,7 +525,7 @@ Vector SSurface::ClosestPointOnThisAndSurface(SSurface *srf2, Vector p) {
|
|||||||
SSurface *srf[2] = { this, srf2 };
|
SSurface *srf[2] = { this, srf2 };
|
||||||
|
|
||||||
for(j = 0; j < 2; j++) {
|
for(j = 0; j < 2; j++) {
|
||||||
(srf[j])->ClosestPointTo(p, &(puv[j]), false);
|
(srf[j])->ClosestPointTo(p, &(puv[j]), /*mustConverge=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < 10; i++) {
|
for(i = 0; i < 10; i++) {
|
||||||
@ -573,8 +573,8 @@ void SSurface::PointOnSurfaces(SSurface *s1, SSurface *s2, double *up, double *v
|
|||||||
|
|
||||||
// Get initial guesses for (u, v) in the other surfaces
|
// Get initial guesses for (u, v) in the other surfaces
|
||||||
Vector p = PointAt(*u, *v);
|
Vector p = PointAt(*u, *v);
|
||||||
(srf[1])->ClosestPointTo(p, &(u[1]), &(v[1]), false);
|
(srf[1])->ClosestPointTo(p, &(u[1]), &(v[1]), /*mustConverge=*/false);
|
||||||
(srf[2])->ClosestPointTo(p, &(u[2]), &(v[2]), false);
|
(srf[2])->ClosestPointTo(p, &(u[2]), &(v[2]), /*mustConverge=*/false);
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < 20; i++) {
|
for(i = 0; i < 20; i++) {
|
||||||
|
@ -190,12 +190,12 @@ void SSurface::SplitInHalf(bool byU, SSurface *sa, SSurface *sb) {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
||||||
int *cnt, int *level,
|
int *cnt, int *level,
|
||||||
List<Inter> *l, bool segment,
|
List<Inter> *l, bool asSegment,
|
||||||
SSurface *sorig)
|
SSurface *sorig)
|
||||||
{
|
{
|
||||||
// Test if the line intersects our axis-aligned bounding box; if no, then
|
// Test if the line intersects our axis-aligned bounding box; if no, then
|
||||||
// no possibility of an intersection
|
// no possibility of an intersection
|
||||||
if(LineEntirelyOutsideBbox(a, b, segment)) return;
|
if(LineEntirelyOutsideBbox(a, b, asSegment)) return;
|
||||||
|
|
||||||
if(*cnt > 2000) {
|
if(*cnt > 2000) {
|
||||||
dbp("!!! too many subdivisions (level=%d)!", *level);
|
dbp("!!! too many subdivisions (level=%d)!", *level);
|
||||||
@ -212,7 +212,7 @@ void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
|||||||
ctrl[degm][0 ]).Plus(
|
ctrl[degm][0 ]).Plus(
|
||||||
ctrl[degm][degn]).ScaledBy(0.25);
|
ctrl[degm][degn]).ScaledBy(0.25);
|
||||||
Inter inter;
|
Inter inter;
|
||||||
sorig->ClosestPointTo(p, &(inter.p.x), &(inter.p.y), false);
|
sorig->ClosestPointTo(p, &(inter.p.x), &(inter.p.y), /*mustConverge=*/false);
|
||||||
if(sorig->PointIntersectingLine(a, b, &(inter.p.x), &(inter.p.y))) {
|
if(sorig->PointIntersectingLine(a, b, &(inter.p.x), &(inter.p.y))) {
|
||||||
Vector p = sorig->PointAt(inter.p.x, inter.p.y);
|
Vector p = sorig->PointAt(inter.p.x, inter.p.y);
|
||||||
// Debug check, verify that the point lies in both surfaces
|
// Debug check, verify that the point lies in both surfaces
|
||||||
@ -232,9 +232,9 @@ void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
|||||||
|
|
||||||
int nextLevel = (*level) + 1;
|
int nextLevel = (*level) + 1;
|
||||||
(*level) = nextLevel;
|
(*level) = nextLevel;
|
||||||
surf0.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, segment, sorig);
|
surf0.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, asSegment, sorig);
|
||||||
(*level) = nextLevel;
|
(*level) = nextLevel;
|
||||||
surf1.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, segment, sorig);
|
surf1.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, asSegment, sorig);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -247,9 +247,9 @@ void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
||||||
List<SInter> *l,
|
List<SInter> *l,
|
||||||
bool seg, bool trimmed, bool inclTangent)
|
bool asSegment, bool trimmed, bool inclTangent)
|
||||||
{
|
{
|
||||||
if(LineEntirelyOutsideBbox(a, b, seg)) return;
|
if(LineEntirelyOutsideBbox(a, b, asSegment)) return;
|
||||||
|
|
||||||
Vector ba = b.Minus(a);
|
Vector ba = b.Minus(a);
|
||||||
double bam = ba.Magnitude();
|
double bam = ba.Magnitude();
|
||||||
@ -266,7 +266,7 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
|||||||
double d = n.Dot(PointAt(0, 0));
|
double d = n.Dot(PointAt(0, 0));
|
||||||
// Trim to line segment now if requested, don't generate points that
|
// Trim to line segment now if requested, don't generate points that
|
||||||
// would just get discarded later.
|
// would just get discarded later.
|
||||||
if(!seg ||
|
if(!asSegment ||
|
||||||
(n.Dot(a) > d + LENGTH_EPS && n.Dot(b) < d - LENGTH_EPS) ||
|
(n.Dot(a) > d + LENGTH_EPS && n.Dot(b) < d - LENGTH_EPS) ||
|
||||||
(n.Dot(b) > d + LENGTH_EPS && n.Dot(a) < d - LENGTH_EPS))
|
(n.Dot(b) > d + LENGTH_EPS && n.Dot(a) < d - LENGTH_EPS))
|
||||||
{
|
{
|
||||||
@ -334,7 +334,7 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
|||||||
} else {
|
} else {
|
||||||
// General numerical solution by subdivision, fallback
|
// General numerical solution by subdivision, fallback
|
||||||
int cnt = 0, level = 0;
|
int cnt = 0, level = 0;
|
||||||
AllPointsIntersectingUntrimmed(a, b, &cnt, &level, &inters, seg, this);
|
AllPointsIntersectingUntrimmed(a, b, &cnt, &level, &inters, asSegment, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove duplicate intersection points
|
// Remove duplicate intersection points
|
||||||
@ -355,7 +355,7 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
|||||||
// Make sure the point lies within the finite line segment
|
// Make sure the point lies within the finite line segment
|
||||||
Vector pxyz = PointAt(puv.x, puv.y);
|
Vector pxyz = PointAt(puv.x, puv.y);
|
||||||
double t = (pxyz.Minus(a)).DivPivoting(ba);
|
double t = (pxyz.Minus(a)).DivPivoting(ba);
|
||||||
if(seg && (t > 1 - LENGTH_EPS/bam || t < LENGTH_EPS/bam)) {
|
if(asSegment && (t > 1 - LENGTH_EPS/bam || t < LENGTH_EPS/bam)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,11 +381,12 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
|||||||
|
|
||||||
void SShell::AllPointsIntersecting(Vector a, Vector b,
|
void SShell::AllPointsIntersecting(Vector a, Vector b,
|
||||||
List<SInter> *il,
|
List<SInter> *il,
|
||||||
bool seg, bool trimmed, bool inclTangent)
|
bool asSegment, bool trimmed, bool inclTangent)
|
||||||
{
|
{
|
||||||
SSurface *ss;
|
SSurface *ss;
|
||||||
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
|
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
|
||||||
ss->AllPointsIntersecting(a, b, il, seg, trimmed, inclTangent);
|
ss->AllPointsIntersecting(a, b, il,
|
||||||
|
asSegment, trimmed, inclTangent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +435,7 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
Vector inter_surf_n[2], inter_edge_n[2];
|
Vector inter_surf_n[2], inter_edge_n[2];
|
||||||
SSurface *srf;
|
SSurface *srf;
|
||||||
for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
|
for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
|
||||||
if(srf->LineEntirelyOutsideBbox(ea, eb, true)) continue;
|
if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
|
||||||
|
|
||||||
SEdgeList *sel = &(srf->edges);
|
SEdgeList *sel = &(srf->edges);
|
||||||
SEdge *se;
|
SEdge *se;
|
||||||
@ -446,7 +447,7 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
if(edge_inters < 2) {
|
if(edge_inters < 2) {
|
||||||
// Edge-on-edge case
|
// Edge-on-edge case
|
||||||
Point2d pm;
|
Point2d pm;
|
||||||
srf->ClosestPointTo(p, &pm, false);
|
srf->ClosestPointTo(p, &pm, /*mustConverge=*/false);
|
||||||
// A vector normal to the surface, at the intersection point
|
// A vector normal to the surface, at the intersection point
|
||||||
inter_surf_n[edge_inters] = srf->NormalAt(pm);
|
inter_surf_n[edge_inters] = srf->NormalAt(pm);
|
||||||
// A vector normal to the intersecting edge (but within the
|
// A vector normal to the intersecting edge (but within the
|
||||||
@ -519,10 +520,10 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
// the additional error from the line intersection.
|
// the additional error from the line intersection.
|
||||||
|
|
||||||
for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
|
for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
|
||||||
if(srf->LineEntirelyOutsideBbox(ea, eb, true)) continue;
|
if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
|
||||||
|
|
||||||
Point2d puv;
|
Point2d puv;
|
||||||
srf->ClosestPointTo(p, &(puv.x), &(puv.y), false);
|
srf->ClosestPointTo(p, &(puv.x), &(puv.y), /*mustConverge=*/false);
|
||||||
Vector pp = srf->PointAt(puv);
|
Vector pp = srf->PointAt(puv);
|
||||||
|
|
||||||
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
|
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
|
||||||
@ -532,8 +533,8 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
|
|
||||||
// Edge-on-face (unless edge-on-edge above superceded)
|
// Edge-on-face (unless edge-on-edge above superceded)
|
||||||
Point2d pin, pout;
|
Point2d pin, pout;
|
||||||
srf->ClosestPointTo(p.Plus(edge_n_in), &pin, false);
|
srf->ClosestPointTo(p.Plus(edge_n_in), &pin, /*mustConverge=*/false);
|
||||||
srf->ClosestPointTo(p.Plus(edge_n_out), &pout, false);
|
srf->ClosestPointTo(p.Plus(edge_n_out), &pout, /*mustConverge=*/false);
|
||||||
|
|
||||||
Vector surf_n_in = srf->NormalAt(pin),
|
Vector surf_n_in = srf->NormalAt(pin),
|
||||||
surf_n_out = srf->NormalAt(pout);
|
surf_n_out = srf->NormalAt(pout);
|
||||||
@ -553,7 +554,8 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
Vector ray = Vector::From(Random(1), Random(1), Random(1));
|
Vector ray = Vector::From(Random(1), Random(1), Random(1));
|
||||||
|
|
||||||
AllPointsIntersecting(
|
AllPointsIntersecting(
|
||||||
p.Minus(ray), p.Plus(ray), &l, false, true, false);
|
p.Minus(ray), p.Plus(ray), &l,
|
||||||
|
/*asSegment=*/false, /*trimmed=*/true, /*inclTangent=*/false);
|
||||||
|
|
||||||
// no intersections means it's outside
|
// no intersections means it's outside
|
||||||
*indir = Class::OUTSIDE;
|
*indir = Class::OUTSIDE;
|
||||||
|
@ -187,10 +187,10 @@ void SSurface::GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SSurface::LineEntirelyOutsideBbox(Vector a, Vector b, bool segment) const {
|
bool SSurface::LineEntirelyOutsideBbox(Vector a, Vector b, bool asSegment) const {
|
||||||
Vector amax, amin;
|
Vector amax, amin;
|
||||||
GetAxisAlignedBounding(&amax, &amin);
|
GetAxisAlignedBounding(&amax, &amin);
|
||||||
if(!Vector::BoundingBoxIntersectsLine(amax, amin, a, b, segment)) {
|
if(!Vector::BoundingBoxIntersectsLine(amax, amin, a, b, asSegment)) {
|
||||||
// The line segment could fail to intersect the bbox, but lie entirely
|
// The line segment could fail to intersect the bbox, but lie entirely
|
||||||
// within it and intersect the surface.
|
// within it and intersect the surface.
|
||||||
if(a.OutsideAndNotOn(amax, amin) && b.OutsideAndNotOn(amax, amin)) {
|
if(a.OutsideAndNotOn(amax, amin) && b.OutsideAndNotOn(amax, amin)) {
|
||||||
@ -367,7 +367,7 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
|
|||||||
for(i = sp + 1; i <= (fpt - 1); i++) {
|
for(i = sp + 1; i <= (fpt - 1); i++) {
|
||||||
Vector p = sc->pts.elem[i].p;
|
Vector p = sc->pts.elem[i].p;
|
||||||
double t;
|
double t;
|
||||||
sb.ClosestPointTo(p, &t, false);
|
sb.ClosestPointTo(p, &t, /*mustConverge=*/false);
|
||||||
Vector pp = sb.PointAt(t);
|
Vector pp = sb.PointAt(t);
|
||||||
if((pp.Minus(p)).Magnitude() > SS.ChordTolMm()/2) {
|
if((pp.Minus(p)).Magnitude() > SS.ChordTolMm()/2) {
|
||||||
tooFar = true;
|
tooFar = true;
|
||||||
@ -402,7 +402,7 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
|
|||||||
MakeEdgesInto(shell, &el, MakeAs::UV);
|
MakeEdgesInto(shell, &el, MakeAs::UV);
|
||||||
|
|
||||||
SPolygon poly = {};
|
SPolygon poly = {};
|
||||||
if(el.AssemblePolygon(&poly, NULL, true)) {
|
if(el.AssemblePolygon(&poly, NULL, /*keepDir=*/true)) {
|
||||||
int i, start = sm->l.n;
|
int i, start = sm->l.n;
|
||||||
if(degm == 1 && degn == 1) {
|
if(degm == 1 && degn == 1) {
|
||||||
// A surface with curvature along one direction only; so
|
// A surface with curvature along one direction only; so
|
||||||
@ -548,14 +548,14 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, Rgb
|
|||||||
|
|
||||||
STrimBy stb0, stb1;
|
STrimBy stb0, stb1;
|
||||||
// The translated curves trim the flat top and bottom surfaces.
|
// The translated curves trim the flat top and bottom surfaces.
|
||||||
stb0 = STrimBy::EntireCurve(this, hc0, false);
|
stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/false);
|
||||||
stb1 = STrimBy::EntireCurve(this, hc1, true);
|
stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/true);
|
||||||
(surface.FindById(hs0))->trim.Add(&stb0);
|
(surface.FindById(hs0))->trim.Add(&stb0);
|
||||||
(surface.FindById(hs1))->trim.Add(&stb1);
|
(surface.FindById(hs1))->trim.Add(&stb1);
|
||||||
|
|
||||||
// The translated curves also trim the surface of extrusion.
|
// The translated curves also trim the surface of extrusion.
|
||||||
stb0 = STrimBy::EntireCurve(this, hc0, true);
|
stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/true);
|
||||||
stb1 = STrimBy::EntireCurve(this, hc1, false);
|
stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/false);
|
||||||
(surface.FindById(hsext))->trim.Add(&stb0);
|
(surface.FindById(hsext))->trim.Add(&stb0);
|
||||||
(surface.FindById(hsext))->trim.Add(&stb1);
|
(surface.FindById(hsext))->trim.Add(&stb1);
|
||||||
|
|
||||||
@ -581,9 +581,9 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, Rgb
|
|||||||
TrimLine *tlp = &(trimLines.elem[WRAP(i-1, trimLines.n)]);
|
TrimLine *tlp = &(trimLines.elem[WRAP(i-1, trimLines.n)]);
|
||||||
|
|
||||||
STrimBy stb;
|
STrimBy stb;
|
||||||
stb = STrimBy::EntireCurve(this, tl->hc, true);
|
stb = STrimBy::EntireCurve(this, tl->hc, /*backwards=*/true);
|
||||||
ss->trim.Add(&stb);
|
ss->trim.Add(&stb);
|
||||||
stb = STrimBy::EntireCurve(this, tlp->hc, false);
|
stb = STrimBy::EntireCurve(this, tlp->hc, /*backwards=*/false);
|
||||||
ss->trim.Add(&stb);
|
ss->trim.Add(&stb);
|
||||||
|
|
||||||
(curve.FindById(tl->hc))->surfA = ss->h;
|
(curve.FindById(tl->hc))->surfA = ss->h;
|
||||||
@ -691,9 +691,9 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
|||||||
hSCurve hcb = curve.AddAndAssignId(&sc);
|
hSCurve hcb = curve.AddAndAssignId(&sc);
|
||||||
|
|
||||||
STrimBy stb;
|
STrimBy stb;
|
||||||
stb = STrimBy::EntireCurve(this, hcb, true);
|
stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true);
|
||||||
(surface.FindById(sc.surfA))->trim.Add(&stb);
|
(surface.FindById(sc.surfA))->trim.Add(&stb);
|
||||||
stb = STrimBy::EntireCurve(this, hcb, false);
|
stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false);
|
||||||
(surface.FindById(sc.surfB))->trim.Add(&stb);
|
(surface.FindById(sc.surfB))->trim.Add(&stb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,9 +716,9 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
|
|||||||
hSCurve hcc = curve.AddAndAssignId(&sc);
|
hSCurve hcc = curve.AddAndAssignId(&sc);
|
||||||
|
|
||||||
STrimBy stb;
|
STrimBy stb;
|
||||||
stb = STrimBy::EntireCurve(this, hcc, false);
|
stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false);
|
||||||
(surface.FindById(sc.surfA))->trim.Add(&stb);
|
(surface.FindById(sc.surfA))->trim.Add(&stb);
|
||||||
stb = STrimBy::EntireCurve(this, hcc, true);
|
stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true);
|
||||||
(surface.FindById(sc.surfB))->trim.Add(&stb);
|
(surface.FindById(sc.surfB))->trim.Add(&stb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -821,7 +821,7 @@ void SShell::MakeFromTransformationOf(SShell *a,
|
|||||||
SSurface *s;
|
SSurface *s;
|
||||||
for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) {
|
for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) {
|
||||||
SSurface n;
|
SSurface n;
|
||||||
n = SSurface::FromTransformationOf(s, t, q, scale, true);
|
n = SSurface::FromTransformationOf(s, t, q, scale, /*includingTrims=*/true);
|
||||||
surface.Add(&n); // keeping the old ID
|
surface.Add(&n); // keeping the old ID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
void ScalePoints(Point2d *pt, Point2d *a, Point2d *b, SSurface *srf) const;
|
void ScalePoints(Point2d *pt, Point2d *a, Point2d *b, SSurface *srf) const;
|
||||||
double ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b,
|
double ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b,
|
||||||
SSurface *srf) const;
|
SSurface *srf) const;
|
||||||
double ScaledDistanceToLine(Point2d pt, Point2d a, Point2d b, bool seg,
|
double ScaledDistanceToLine(Point2d pt, Point2d a, Point2d b, bool asSegment,
|
||||||
SSurface *srf) const;
|
SSurface *srf) const;
|
||||||
|
|
||||||
void InsertEdge(Point2d a, Point2d b, SSurface *srf);
|
void InsertEdge(Point2d a, Point2d b, SSurface *srf);
|
||||||
@ -86,7 +86,7 @@ public:
|
|||||||
|
|
||||||
Vector PointAt(double t) const;
|
Vector PointAt(double t) const;
|
||||||
Vector TangentAt(double t) const;
|
Vector TangentAt(double t) const;
|
||||||
void ClosestPointTo(Vector p, double *t, bool converge=true) const;
|
void ClosestPointTo(Vector p, double *t, bool mustConverge=true) const;
|
||||||
void SplitAt(double t, SBezier *bef, SBezier *aft) const;
|
void SplitAt(double t, SBezier *bef, SBezier *aft) const;
|
||||||
bool PointOnThisAndCurve(const SBezier *sbb, Vector *p) const;
|
bool PointOnThisAndCurve(const SBezier *sbb, Vector *p) const;
|
||||||
|
|
||||||
@ -233,7 +233,7 @@ public:
|
|||||||
Vector start;
|
Vector start;
|
||||||
Vector finish;
|
Vector finish;
|
||||||
|
|
||||||
static STrimBy EntireCurve(SShell *shell, hSCurve hsc, bool bkwds);
|
static STrimBy EntireCurve(SShell *shell, hSCurve hsc, bool backwards);
|
||||||
};
|
};
|
||||||
|
|
||||||
// An intersection point between a line and a surface
|
// An intersection point between a line and a surface
|
||||||
@ -317,15 +317,15 @@ public:
|
|||||||
void SplitInHalf(bool byU, SSurface *sa, SSurface *sb);
|
void SplitInHalf(bool byU, SSurface *sa, SSurface *sb);
|
||||||
void AllPointsIntersecting(Vector a, Vector b,
|
void AllPointsIntersecting(Vector a, Vector b,
|
||||||
List<SInter> *l,
|
List<SInter> *l,
|
||||||
bool seg, bool trimmed, bool inclTangent);
|
bool asSegment, bool trimmed, bool inclTangent);
|
||||||
void AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
void AllPointsIntersectingUntrimmed(Vector a, Vector b,
|
||||||
int *cnt, int *level,
|
int *cnt, int *level,
|
||||||
List<Inter> *l, bool segment,
|
List<Inter> *l, bool asSegment,
|
||||||
SSurface *sorig);
|
SSurface *sorig);
|
||||||
|
|
||||||
void ClosestPointTo(Vector p, Point2d *puv, bool converge=true);
|
void ClosestPointTo(Vector p, Point2d *puv, bool mustConverge=true);
|
||||||
void ClosestPointTo(Vector p, double *u, double *v, bool converge=true);
|
void ClosestPointTo(Vector p, double *u, double *v, bool mustConverge=true);
|
||||||
bool ClosestPointNewton(Vector p, double *u, double *v, bool converge=true) const;
|
bool ClosestPointNewton(Vector p, double *u, double *v, bool mustConverge=true) const;
|
||||||
|
|
||||||
bool PointIntersectingLine(Vector p0, Vector p1, double *u, double *v) const;
|
bool PointIntersectingLine(Vector p0, Vector p1, double *u, double *v) const;
|
||||||
Vector ClosestPointOnThisAndSurface(SSurface *srf2, Vector p);
|
Vector ClosestPointOnThisAndSurface(SSurface *srf2, Vector p);
|
||||||
@ -335,7 +335,7 @@ public:
|
|||||||
void TangentsAt(double u, double v, Vector *tu, Vector *tv) const;
|
void TangentsAt(double u, double v, Vector *tu, Vector *tv) const;
|
||||||
Vector NormalAt(Point2d puv) const;
|
Vector NormalAt(Point2d puv) const;
|
||||||
Vector NormalAt(double u, double v) const;
|
Vector NormalAt(double u, double v) const;
|
||||||
bool LineEntirelyOutsideBbox(Vector a, Vector b, bool segment) const;
|
bool LineEntirelyOutsideBbox(Vector a, Vector b, bool asSegment) const;
|
||||||
void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const;
|
void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const;
|
||||||
bool CoincidentWithPlane(Vector n, double d) const;
|
bool CoincidentWithPlane(Vector n, double d) const;
|
||||||
bool CoincidentWith(SSurface *ss, bool sameNormal) const;
|
bool CoincidentWith(SSurface *ss, bool sameNormal) const;
|
||||||
@ -387,7 +387,7 @@ public:
|
|||||||
void MakeIntersectionCurvesAgainst(SShell *against, SShell *into);
|
void MakeIntersectionCurvesAgainst(SShell *against, SShell *into);
|
||||||
void MakeClassifyingBsps(SShell *useCurvesFrom);
|
void MakeClassifyingBsps(SShell *useCurvesFrom);
|
||||||
void AllPointsIntersecting(Vector a, Vector b, List<SInter> *il,
|
void AllPointsIntersecting(Vector a, Vector b, List<SInter> *il,
|
||||||
bool seg, bool trimmed, bool inclTangent);
|
bool asSegment, bool trimmed, bool inclTangent);
|
||||||
void MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
|
void MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
|
||||||
SEdgeList *el, SShell *useCurvesFrom);
|
SEdgeList *el, SShell *useCurvesFrom);
|
||||||
void RewriteSurfaceHandlesForCurves(SShell *a, SShell *b);
|
void RewriteSurfaceHandlesForCurves(SShell *a, SShell *b);
|
||||||
|
@ -216,8 +216,8 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
|||||||
p0 = n.ScaledBy(d).Plus(alu.ScaledBy(pm.Dot(alu)));
|
p0 = n.ScaledBy(d).Plus(alu.ScaledBy(pm.Dot(alu)));
|
||||||
|
|
||||||
List<SInter> inters = {};
|
List<SInter> inters = {};
|
||||||
sext->AllPointsIntersecting(
|
sext->AllPointsIntersecting(p0, p0.Plus(dp), &inters,
|
||||||
p0, p0.Plus(dp), &inters, false, false, true);
|
/*asSegment=*/false, /*trimmed=*/false, /*inclTangent=*/true);
|
||||||
|
|
||||||
SInter *si;
|
SInter *si;
|
||||||
for(si = inters.First(); si; si = inters.NextAfter(si)) {
|
for(si = inters.First(); si; si = inters.NextAfter(si)) {
|
||||||
@ -283,14 +283,15 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
|||||||
pa = pa.Plus(axisc);
|
pa = pa.Plus(axisc);
|
||||||
pb = pb.Plus(axisc);
|
pb = pb.Plus(axisc);
|
||||||
|
|
||||||
b->AllPointsIntersecting(pa, pb, &inters, true, false, false);
|
b->AllPointsIntersecting(pa, pb, &inters,
|
||||||
|
/*asSegment=*/true,/*trimmed=*/false, /*inclTangent=*/false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SInter *si;
|
SInter *si;
|
||||||
for(si = inters.First(); si; si = inters.NextAfter(si)) {
|
for(si = inters.First(); si; si = inters.NextAfter(si)) {
|
||||||
Vector p = (si->p).Minus(axis.ScaledBy((si->p).Dot(axis)));
|
Vector p = (si->p).Minus(axis.ScaledBy((si->p).Dot(axis)));
|
||||||
double ub, vb;
|
double ub, vb;
|
||||||
b->ClosestPointTo(p, &ub, &vb, true);
|
b->ClosestPointTo(p, &ub, &vb, /*mustConverge=*/true);
|
||||||
SSurface plane;
|
SSurface plane;
|
||||||
plane = SSurface::FromPlane(p, axis.Normal(0), axis.Normal(1));
|
plane = SSurface::FromPlane(p, axis.Normal(0), axis.Normal(1));
|
||||||
|
|
||||||
@ -324,7 +325,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
|||||||
List<SInter> lsi = {};
|
List<SInter> lsi = {};
|
||||||
|
|
||||||
srfB->AllPointsIntersecting(se->a, se->b, &lsi,
|
srfB->AllPointsIntersecting(se->a, se->b, &lsi,
|
||||||
true, true, false);
|
/*asSegment=*/true, /*trimmed=*/true, /*inclTangent=*/false);
|
||||||
if(lsi.n == 0) continue;
|
if(lsi.n == 0) continue;
|
||||||
|
|
||||||
// Find the other surface that this curve trims.
|
// Find the other surface that this curve trims.
|
||||||
|
@ -434,9 +434,9 @@ void SPolygon::UvGridTriangulateInto(SMesh *mesh, SSurface *srf) {
|
|||||||
lj = {};
|
lj = {};
|
||||||
double v = 0;
|
double v = 0;
|
||||||
li.Add(&v);
|
li.Add(&v);
|
||||||
srf->MakeTriangulationGridInto(&li, 0, 1, true);
|
srf->MakeTriangulationGridInto(&li, 0, 1, /*swapped=*/true);
|
||||||
lj.Add(&v);
|
lj.Add(&v);
|
||||||
srf->MakeTriangulationGridInto(&lj, 0, 1, false);
|
srf->MakeTriangulationGridInto(&lj, 0, 1, /*swapped=*/false);
|
||||||
|
|
||||||
// Now iterate over each quad in the grid. If it's outside the polygon,
|
// Now iterate over each quad in the grid. If it's outside the polygon,
|
||||||
// or if it intersects the polygon, then we discard it. Otherwise we
|
// or if it intersects the polygon, then we discard it. Otherwise we
|
||||||
@ -486,7 +486,7 @@ void SPolygon::UvGridTriangulateInto(SMesh *mesh, SSurface *srf) {
|
|||||||
|
|
||||||
holes.CullExtraneousEdges();
|
holes.CullExtraneousEdges();
|
||||||
SPolygon hp = {};
|
SPolygon hp = {};
|
||||||
holes.AssemblePolygon(&hp, NULL, true);
|
holes.AssemblePolygon(&hp, NULL, /*keepDir=*/true);
|
||||||
|
|
||||||
SContour *sc;
|
SContour *sc;
|
||||||
for(sc = hp.l.First(); sc; sc = hp.l.NextAfter(sc)) {
|
for(sc = hp.l.First(); sc; sc = hp.l.NextAfter(sc)) {
|
||||||
|
@ -650,7 +650,7 @@ void TextWindow::EditControlDone(const char *s) {
|
|||||||
|
|
||||||
switch(edit.meaning) {
|
switch(edit.meaning) {
|
||||||
case Edit::TIMES_REPEATED: {
|
case Edit::TIMES_REPEATED: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) {
|
if(e) {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
@ -700,7 +700,7 @@ void TextWindow::EditControlDone(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::GROUP_SCALE: {
|
case Edit::GROUP_SCALE: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = e->Eval();
|
double ev = e->Eval();
|
||||||
if(fabs(ev) < 1e-6) {
|
if(fabs(ev) < 1e-6) {
|
||||||
@ -732,7 +732,7 @@ void TextWindow::EditControlDone(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::GROUP_OPACITY: {
|
case Edit::GROUP_OPACITY: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) {
|
if(e) {
|
||||||
double alpha = e->Eval();
|
double alpha = e->Eval();
|
||||||
if(alpha < 0 || alpha > 1) {
|
if(alpha < 0 || alpha > 1) {
|
||||||
@ -758,7 +758,7 @@ void TextWindow::EditControlDone(const char *s) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::STEP_DIM_FINISH: {
|
case Edit::STEP_DIM_FINISH: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(!e) {
|
if(!e) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -774,7 +774,7 @@ void TextWindow::EditControlDone(const char *s) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Edit::TANGENT_ARC_RADIUS: {
|
case Edit::TANGENT_ARC_RADIUS: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(!e) break;
|
if(!e) break;
|
||||||
if(e->Eval() < LENGTH_EPS) {
|
if(e->Eval() < LENGTH_EPS) {
|
||||||
Error("Radius cannot be zero or negative.");
|
Error("Radius cannot be zero or negative.");
|
||||||
|
@ -865,7 +865,7 @@ void TextWindow::Paint() {
|
|||||||
// Move the quad down a bit, so that the descenders
|
// Move the quad down a bit, so that the descenders
|
||||||
// still have the correct background.
|
// still have the correct background.
|
||||||
y += adj;
|
y += adj;
|
||||||
ssglAxisAlignedQuad(x, x + CHAR_WIDTH, y, y + bh, false);
|
ssglAxisAlignedQuad(x, x + CHAR_WIDTH, y, y + bh, /*lone=*/false);
|
||||||
y -= adj;
|
y -= adj;
|
||||||
}
|
}
|
||||||
} else if(a == 1) {
|
} else if(a == 1) {
|
||||||
|
@ -54,7 +54,7 @@ static ToolIcon Toolbar[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void GraphicsWindow::ToolbarDraw() {
|
void GraphicsWindow::ToolbarDraw() {
|
||||||
ToolbarDrawOrHitTest(0, 0, true, NULL);
|
ToolbarDrawOrHitTest(0, 0, /*paint=*/true, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
||||||
@ -62,7 +62,7 @@ bool GraphicsWindow::ToolbarMouseMoved(int x, int y) {
|
|||||||
y += ((int)height/2);
|
y += ((int)height/2);
|
||||||
|
|
||||||
Command nh = Command::NONE;
|
Command nh = Command::NONE;
|
||||||
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
bool withinToolbar = ToolbarDrawOrHitTest(x, y, /*paint=*/false, &nh);
|
||||||
if(!withinToolbar) nh = Command::NONE;
|
if(!withinToolbar) nh = Command::NONE;
|
||||||
|
|
||||||
if(nh != toolbarTooltipped) {
|
if(nh != toolbarTooltipped) {
|
||||||
@ -89,7 +89,7 @@ bool GraphicsWindow::ToolbarMouseDown(int x, int y) {
|
|||||||
y += ((int)height/2);
|
y += ((int)height/2);
|
||||||
|
|
||||||
Command nh = Command::NONE;
|
Command nh = Command::NONE;
|
||||||
bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh);
|
bool withinToolbar = ToolbarDrawOrHitTest(x, y, /*paint=*/false, &nh);
|
||||||
// They might have clicked within the toolbar, but not on a button.
|
// They might have clicked within the toolbar, but not on a button.
|
||||||
if(withinToolbar && nh != Command::NONE) {
|
if(withinToolbar && nh != Command::NONE) {
|
||||||
for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
|
for(int i = 0; SS.GW.menu[i].level >= 0; i++) {
|
||||||
|
12
src/util.cpp
12
src/util.cpp
@ -148,14 +148,14 @@ void SolveSpace::Error(const char *str, ...)
|
|||||||
{
|
{
|
||||||
va_list f;
|
va_list f;
|
||||||
va_start(f, str);
|
va_start(f, str);
|
||||||
DoStringForMessageBox(str, f, true);
|
DoStringForMessageBox(str, f, /*error=*/true);
|
||||||
va_end(f);
|
va_end(f);
|
||||||
}
|
}
|
||||||
void SolveSpace::Message(const char *str, ...)
|
void SolveSpace::Message(const char *str, ...)
|
||||||
{
|
{
|
||||||
va_list f;
|
va_list f;
|
||||||
va_start(f, str);
|
va_start(f, str);
|
||||||
DoStringForMessageBox(str, f, false);
|
DoStringForMessageBox(str, f, /*error=*/false);
|
||||||
va_end(f);
|
va_end(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,7 +749,7 @@ bool Vector::BoundingBoxesDisjoint(Vector amax, Vector amin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Vector::BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
bool Vector::BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
||||||
Vector p0, Vector p1, bool segment)
|
Vector p0, Vector p1, bool asSegment)
|
||||||
{
|
{
|
||||||
Vector dp = p1.Minus(p0);
|
Vector dp = p1.Minus(p0);
|
||||||
double lp = dp.Magnitude();
|
double lp = dp.Magnitude();
|
||||||
@ -767,7 +767,7 @@ bool Vector::BoundingBoxIntersectsLine(Vector amax, Vector amin,
|
|||||||
double t = (d - p0.Element(i)) / dp.Element(i);
|
double t = (d - p0.Element(i)) / dp.Element(i);
|
||||||
Vector p = p0.Plus(dp.ScaledBy(t));
|
Vector p = p0.Plus(dp.ScaledBy(t));
|
||||||
|
|
||||||
if(segment && (t < -LENGTH_EPS || t > (lp+LENGTH_EPS))) continue;
|
if(asSegment && (t < -LENGTH_EPS || t > (lp+LENGTH_EPS))) continue;
|
||||||
|
|
||||||
if(p.Element(j) > amax.Element(j) + LENGTH_EPS) continue;
|
if(p.Element(j) > amax.Element(j) + LENGTH_EPS) continue;
|
||||||
if(p.Element(k) > amax.Element(k) + LENGTH_EPS) continue;
|
if(p.Element(k) > amax.Element(k) + LENGTH_EPS) continue;
|
||||||
@ -998,14 +998,14 @@ double Point2d::Dot(Point2d p) const {
|
|||||||
return x*p.x + y*p.y;
|
return x*p.x + y*p.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
double Point2d::DistanceToLine(const Point2d &p0, const Point2d &dp, bool segment) const {
|
double Point2d::DistanceToLine(const Point2d &p0, const Point2d &dp, bool asSegment) const {
|
||||||
double m = dp.x*dp.x + dp.y*dp.y;
|
double m = dp.x*dp.x + dp.y*dp.y;
|
||||||
if(m < LENGTH_EPS*LENGTH_EPS) return VERY_POSITIVE;
|
if(m < LENGTH_EPS*LENGTH_EPS) return VERY_POSITIVE;
|
||||||
|
|
||||||
// Let our line be p = p0 + t*dp, for a scalar t from 0 to 1
|
// Let our line be p = p0 + t*dp, for a scalar t from 0 to 1
|
||||||
double t = (dp.x*(x - p0.x) + dp.y*(y - p0.y))/m;
|
double t = (dp.x*(x - p0.x) + dp.y*(y - p0.y))/m;
|
||||||
|
|
||||||
if(segment) {
|
if(asSegment) {
|
||||||
if(t < 0.0) return DistanceTo(p0);
|
if(t < 0.0) return DistanceTo(p0);
|
||||||
if(t > 1.0) return DistanceTo(p0.Plus(dp));
|
if(t > 1.0) return DistanceTo(p0.Plus(dp));
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ void TextWindow::ScreenChangeViewProjection(int link, uint32_t v) {
|
|||||||
bool TextWindow::EditControlDoneForView(const char *s) {
|
bool TextWindow::EditControlDoneForView(const char *s) {
|
||||||
switch(edit.meaning) {
|
switch(edit.meaning) {
|
||||||
case Edit::VIEW_SCALE: {
|
case Edit::VIEW_SCALE: {
|
||||||
Expr *e = Expr::From(s, true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(e) {
|
if(e) {
|
||||||
double v = e->Eval() / SS.MmPerUnit();
|
double v = e->Eval() / SS.MmPerUnit();
|
||||||
if(v > LENGTH_EPS) {
|
if(v > LENGTH_EPS) {
|
||||||
|
Loading…
Reference in New Issue
Block a user