From 9dd67c7ba05e1fe33768f8540e36c2395d981227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?=
Date: Sat, 3 Apr 2021 19:07:53 +0200
Subject: [PATCH] Use Range-based for Loops Instead of NextAfter for all IdList
Objects
Based on commit '3b395bb5a7' by pjanx
Resolves a performance regression of iteration being O(n * log n)
rather than O(n).
---
src/clipboard.cpp | 19 ++++++-------
src/draw.cpp | 17 ++++++-----
src/exportstep.cpp | 11 ++++----
src/exportvector.cpp | 57 +++++++++++++++++++------------------
src/file.cpp | 30 ++++++++++----------
src/graphicswin.cpp | 50 +++++++++++++++------------------
src/groupmesh.cpp | 20 ++++++-------
src/modify.cpp | 48 +++++++++++++++-----------------
src/mouse.cpp | 18 ++++++------
src/srf/boolean.cpp | 65 ++++++++++++++++++++-----------------------
src/srf/merge.cpp | 7 ++---
src/srf/raycast.cpp | 34 +++++++++++-----------
src/srf/surface.cpp | 32 +++++++++------------
src/srf/surfinter.cpp | 34 +++++++++++-----------
src/style.cpp | 9 +++---
15 files changed, 210 insertions(+), 241 deletions(-)
diff --git a/src/clipboard.cpp b/src/clipboard.cpp
index d43ec458..96265008 100644
--- a/src/clipboard.cpp
+++ b/src/clipboard.cpp
@@ -138,18 +138,17 @@ void GraphicsWindow::CopySelection() {
}
}
- Constraint *c;
- for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
- if(!SS.clipboard.ContainsEntity(c->ptA) ||
- !SS.clipboard.ContainsEntity(c->ptB) ||
- !SS.clipboard.ContainsEntity(c->entityA) ||
- !SS.clipboard.ContainsEntity(c->entityB) ||
- !SS.clipboard.ContainsEntity(c->entityC) ||
- !SS.clipboard.ContainsEntity(c->entityD) ||
- c->type == Constraint::Type::COMMENT) {
+ for(Constraint &c : SK.constraint) {
+ if(!SS.clipboard.ContainsEntity(c.ptA) ||
+ !SS.clipboard.ContainsEntity(c.ptB) ||
+ !SS.clipboard.ContainsEntity(c.entityA) ||
+ !SS.clipboard.ContainsEntity(c.entityB) ||
+ !SS.clipboard.ContainsEntity(c.entityC) ||
+ !SS.clipboard.ContainsEntity(c.entityD) ||
+ c.type == Constraint::Type::COMMENT) {
continue;
}
- SS.clipboard.c.Add(c);
+ SS.clipboard.c.Add(&c);
}
}
diff --git a/src/draw.cpp b/src/draw.cpp
index ccaeb961..3610f201 100644
--- a/src/draw.cpp
+++ b/src/draw.cpp
@@ -210,16 +210,15 @@ void GraphicsWindow::SelectByMarquee() {
BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, VERY_NEGATIVE),
Vector::From(orig.mouse.x, orig.mouse.y, VERY_POSITIVE));
- Entity *e;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != SS.GW.activeGroup) continue;
- if(e->IsFace() || e->IsDistance()) continue;
- if(!e->IsVisible()) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != SS.GW.activeGroup) continue;
+ if(e.IsFace() || e.IsDistance()) continue;
+ if(!e.IsVisible()) continue;
bool entityHasBBox;
- BBox entityBBox = e->GetOrGenerateScreenBBox(&entityHasBBox);
+ BBox entityBBox = e.GetOrGenerateScreenBBox(&entityHasBBox);
if(entityHasBBox && entityBBox.Overlaps(marqueeBBox)) {
- MakeSelected(e->h);
+ MakeSelected(e.h);
}
}
}
@@ -412,8 +411,8 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
cached.projRight = projRight;
cached.projUp = projUp;
cached.scale = scale;
- for(Entity *e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- e->screenBBoxValid = false;
+ for(Entity &e : SK.entity) {
+ e.screenBBoxValid = false;
}
}
diff --git a/src/exportstep.cpp b/src/exportstep.cpp
index db42dc08..5bfa57f6 100644
--- a/src/exportstep.cpp
+++ b/src/exportstep.cpp
@@ -353,22 +353,21 @@ void StepFileWriter::ExportSurfacesTo(const Platform::Path &filename) {
advancedFaces = {};
- SSurface *ss;
- for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) {
- if(ss->trim.IsEmpty())
+ for(SSurface &ss : shell->surface) {
+ if(ss.trim.IsEmpty())
continue;
// Get all of the loops of Beziers that trim our surface (with each
// Bezier split so that we use the section as t goes from 0 to 1), and
// the piecewise linearization of those loops in xyz space.
SBezierList sbl = {};
- ss->MakeSectionEdgesInto(shell, NULL, &sbl);
+ ss.MakeSectionEdgesInto(shell, NULL, &sbl);
// Apply the export scale factor.
- ss->ScaleSelfBy(1.0/SS.exportScale);
+ ss.ScaleSelfBy(1.0/SS.exportScale);
sbl.ScaleSelfBy(1.0/SS.exportScale);
- ExportSurface(ss, &sbl);
+ ExportSurface(&ss, &sbl);
sbl.Clear();
}
diff --git a/src/exportvector.cpp b/src/exportvector.cpp
index 97730997..5a3c5d36 100644
--- a/src/exportvector.cpp
+++ b/src/exportvector.cpp
@@ -170,22 +170,21 @@ public:
}
if(writer->constraint) {
- Constraint *c;
- for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) {
- if(!writer->NeedToOutput(c)) continue;
- switch(c->type) {
+ for(Constraint &c : *writer->constraint) {
+ if(!writer->NeedToOutput(&c)) continue;
+ switch(c.type) {
case Constraint::Type::PT_PT_DISTANCE: {
- Vector ap = SK.GetEntity(c->ptA)->PointGetNum();
- Vector bp = SK.GetEntity(c->ptB)->PointGetNum();
- Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset);
+ Vector ap = SK.GetEntity(c.ptA)->PointGetNum();
+ Vector bp = SK.GetEntity(c.ptB)->PointGetNum();
+ Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c.disp.offset);
writeAlignedDimension(xfrm(ap), xfrm(bp), xfrm(ref),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
break;
}
case Constraint::Type::PT_LINE_DISTANCE: {
- Vector pt = SK.GetEntity(c->ptA)->PointGetNum();
- Entity *line = SK.GetEntity(c->entityA);
+ Vector pt = SK.GetEntity(c.ptA)->PointGetNum();
+ Entity *line = SK.GetEntity(c.entityA);
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
Vector dl = lB.Minus(lA);
@@ -194,7 +193,7 @@ public:
if(pt.Equals(closest)) break;
- Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c->disp.offset);
+ Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c.disp.offset);
Vector refClosest = ref.ClosestPointOnLine(lA, dl);
double ddl = dl.Dot(dl);
@@ -209,54 +208,54 @@ public:
Vector xdl = xfrm(lB).Minus(xfrm(lA));
writeLinearDimension(xfrm(pt), xfrm(refClosest), xfrm(ref),
- xfrm(ref), c->Label(),
+ xfrm(ref), c.Label(),
atan2(xdl.y, xdl.x) / PI * 180.0 + 90.0, 0.0,
- c->GetStyle(), c->valA);
+ c.GetStyle(), c.valA);
break;
}
case Constraint::Type::DIAMETER: {
- Entity *circle = SK.GetEntity(c->entityA);
+ Entity *circle = SK.GetEntity(c.entityA);
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
Vector n = q.RotationN().WithMagnitude(1);
double r = circle->CircleGetRadiusNum();
- Vector ref = center.Plus(c->disp.offset);
+ Vector ref = center.Plus(c.disp.offset);
// Force the label into the same plane as the circle.
ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));
Vector rad = ref.Minus(center).WithMagnitude(r);
- if(/*isRadius*/c->other) {
+ if(/*isRadius*/c.other) {
writeRadialDimension(
xfrm(center), xfrm(center.Plus(rad)),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
} else {
writeDiametricDimension(
xfrm(center.Minus(rad)), xfrm(center.Plus(rad)),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
}
break;
}
case Constraint::Type::ANGLE: {
- Entity *a = SK.GetEntity(c->entityA);
- Entity *b = SK.GetEntity(c->entityB);
+ Entity *a = SK.GetEntity(c.entityA);
+ Entity *b = SK.GetEntity(c.entityB);
Vector a0 = a->VectorGetStartPoint();
Vector b0 = b->VectorGetStartPoint();
Vector da = a->VectorGetNum();
Vector db = b->VectorGetNum();
- if(/*otherAngle*/c->other) {
+ if(/*otherAngle*/c.other) {
a0 = a0.Plus(da);
da = da.ScaledBy(-1);
}
bool skew = false;
- Vector ref = c->disp.offset;
+ Vector ref = c.disp.offset;
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da), b0, b0.Plus(db),
&skew);
- if(!skew) ref = pi.Plus(c->disp.offset);
+ if(!skew) ref = pi.Plus(c.disp.offset);
Vector norm = da.Cross(db);
Vector dna = norm.Cross(da).WithMagnitude(1.0);
@@ -277,7 +276,7 @@ public:
Vector bisect = da.WithMagnitude(1.0).ScaledBy(cos(thetaf / 2.0)).Plus(
dna.ScaledBy(sin(thetaf / 2.0)));
- ref = pi.Plus(bisect.WithMagnitude(c->disp.offset.Magnitude()));
+ ref = pi.Plus(bisect.WithMagnitude(c.disp.offset.Magnitude()));
// Get lines again to write exact line.
a0 = a->VectorGetStartPoint();
@@ -287,15 +286,15 @@ public:
writeAngularDimension(
xfrm(a0), xfrm(a0.Plus(da)), xfrm(b0), xfrm(b0.Plus(db)), xfrm(ref),
- xfrm(ref), c->Label(), c->GetStyle(), c->valA);
+ xfrm(ref), c.Label(), c.GetStyle(), c.valA);
break;
}
case Constraint::Type::COMMENT: {
- Style *st = SK.style.FindById(c->GetStyle());
- writeText(xfrm(c->disp.offset), c->Label(),
- Style::TextHeight(c->GetStyle()) / SS.GW.scale,
- st->textAngle, st->textOrigin, c->GetStyle());
+ Style *st = SK.style.FindById(c.GetStyle());
+ writeText(xfrm(c.disp.offset), c.Label(),
+ Style::TextHeight(c.GetStyle()) / SS.GW.scale,
+ st->textAngle, st->textOrigin, c.GetStyle());
break;
}
diff --git a/src/file.cpp b/src/file.cpp
index 160b5ec7..4e3b50d3 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -354,19 +354,18 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
}
SShell *s = &g->runningShell;
- SSurface *srf;
- for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) {
+ for(SSurface &srf : s->surface) {
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
- srf->h.v, srf->color.ToPackedInt(), srf->face, srf->degm, srf->degn);
- for(i = 0; i <= srf->degm; i++) {
- for(j = 0; j <= srf->degn; j++) {
+ srf.h.v, srf.color.ToPackedInt(), srf.face, srf.degm, srf.degn);
+ for(i = 0; i <= srf.degm; i++) {
+ for(j = 0; j <= srf.degn; j++) {
fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n",
- i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]);
+ i, j, CO(srf.ctrl[i][j]), srf.weight[i][j]);
}
}
STrimBy *stb;
- for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) {
+ for(stb = srf.trim.First(); stb; stb = srf.trim.NextAfter(stb)) {
fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n",
stb->curve.v, stb->backwards ? 1 : 0,
CO(stb->start), CO(stb->finish));
@@ -374,21 +373,20 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
fprintf(fh, "AddSurface\n");
}
- SCurve *sc;
- for(sc = s->curve.First(); sc; sc = s->curve.NextAfter(sc)) {
+ for(SCurve &sc : s->curve) {
fprintf(fh, "Curve %08x %d %d %08x %08x\n",
- sc->h.v,
- sc->isExact ? 1 : 0, sc->exact.deg,
- sc->surfA.v, sc->surfB.v);
+ sc.h.v,
+ sc.isExact ? 1 : 0, sc.exact.deg,
+ sc.surfA.v, sc.surfB.v);
- if(sc->isExact) {
- for(i = 0; i <= sc->exact.deg; i++) {
+ if(sc.isExact) {
+ for(i = 0; i <= sc.exact.deg; i++) {
fprintf(fh, "CCtrl %d %.20f %.20f %.20f Weight %.20f\n",
- i, CO(sc->exact.ctrl[i]), sc->exact.weight[i]);
+ i, CO(sc.exact.ctrl[i]), sc.exact.weight[i]);
}
}
SCurvePt *scpt;
- for(scpt = sc->pts.First(); scpt; scpt = sc->pts.NextAfter(scpt)) {
+ for(scpt = sc.pts.First(); scpt; scpt = sc.pts.NextAfter(scpt)) {
fprintf(fh, "CurvePt %d %.20f %.20f %.20f\n",
scpt->vertex ? 1 : 0, CO(scpt->p));
}
diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp
index 8427fa1e..5422a579 100644
--- a/src/graphicswin.cpp
+++ b/src/graphicswin.cpp
@@ -968,20 +968,19 @@ void GraphicsWindow::ForceTextWindowShown() {
}
void GraphicsWindow::DeleteTaggedRequests() {
- Request *r;
// Delete any requests that were affected by this deletion.
- for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) {
- if(r->workplane == Entity::FREE_IN_3D) continue;
- if(!r->workplane.isFromRequest()) continue;
- Request *wrkpl = SK.GetRequest(r->workplane.request());
+ for(Request &r : SK.request) {
+ if(r.workplane == Entity::FREE_IN_3D) continue;
+ if(!r.workplane.isFromRequest()) continue;
+ Request *wrkpl = SK.GetRequest(r.workplane.request());
if(wrkpl->tag)
- r->tag = 1;
+ r.tag = 1;
}
// Rewrite any point-coincident constraints that were affected by this
// deletion.
- for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) {
- if(!r->tag) continue;
- FixConstraintsForRequestBeingDeleted(r->h);
+ for(Request &r : SK.request) {
+ if(!r.tag) continue;
+ FixConstraintsForRequestBeingDeleted(r.h);
}
// and then delete the tagged requests.
SK.request.RemoveTagged();
@@ -1045,9 +1044,8 @@ void GraphicsWindow::MenuEdit(Command id) {
SS.centerOfMass.draw = false;
// This clears the marks drawn to indicate which points are
// still free to drag.
- Param *p;
- for(p = SK.param.First(); p; p = SK.param.NextAfter(p)) {
- p->free = false;
+ for(Param &p : SK.param) {
+ p.free = false;
}
if(SS.exportMode) {
SS.exportMode = false;
@@ -1057,13 +1055,12 @@ void GraphicsWindow::MenuEdit(Command id) {
break;
case Command::SELECT_ALL: {
- Entity *e;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != SS.GW.activeGroup) continue;
- if(e->IsFace() || e->IsDistance()) continue;
- if(!e->IsVisible()) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != SS.GW.activeGroup) continue;
+ if(e.IsFace() || e.IsDistance()) continue;
+ if(!e.IsVisible()) continue;
- SS.GW.MakeSelected(e->h);
+ SS.GW.MakeSelected(e.h);
}
SS.GW.Invalidate();
SS.ScheduleShowTW();
@@ -1071,24 +1068,23 @@ void GraphicsWindow::MenuEdit(Command id) {
}
case Command::SELECT_CHAIN: {
- Entity *e;
int newlySelected = 0;
bool didSomething;
do {
didSomething = false;
- for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
- if(e->group != SS.GW.activeGroup) continue;
- if(!e->HasEndpoints()) continue;
- if(!e->IsVisible()) continue;
+ for(Entity &e : SK.entity) {
+ if(e.group != SS.GW.activeGroup) continue;
+ if(!e.HasEndpoints()) continue;
+ if(!e.IsVisible()) continue;
- Vector st = e->EndpointStart(),
- fi = e->EndpointFinish();
+ Vector st = e.EndpointStart(),
+ fi = e.EndpointFinish();
bool onChain = false, alreadySelected = false;
List