Add and use List::Last(). NFC.

pull/479/head
Ryan Pavlik 2019-08-20 10:43:39 -05:00 committed by whitequark
parent c5f3cd151a
commit 231dff6cd9
7 changed files with 21 additions and 19 deletions

View File

@ -250,6 +250,10 @@ public:
const T *First() const { const T *First() const {
return IsEmpty() ? nullptr : &(elem[0]); return IsEmpty() ? nullptr : &(elem[0]);
} }
T *Last() { return IsEmpty() ? nullptr : &(elem[n - 1]); }
const T *Last() const { return IsEmpty() ? nullptr : &(elem[n - 1]); }
T *NextAfter(T *prev) { T *NextAfter(T *prev) {
if(IsEmpty() || !prev) return NULL; if(IsEmpty() || !prev) return NULL;
if(prev - First() == (n - 1)) return NULL; if(prev - First() == (n - 1)) return NULL;

View File

@ -121,7 +121,7 @@ int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) {
List<int> listOfTrims = {}; List<int> listOfTrims = {};
SBezier *sb = &(loop->l[loop->l.n - 1]); SBezier *sb = loop->l.Last();
// Generate "exactly closed" contours, with the same vertex id for the // Generate "exactly closed" contours, with the same vertex id for the
// finish of a previous edge and the start of the next one. So we need // finish of a previous edge and the start of the next one. So we need

View File

@ -343,7 +343,7 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
// A group will have either a mesh or a shell, but not both; but the code // A group will have either a mesh or a shell, but not both; but the code
// to print either of those just does nothing if the mesh/shell is empty. // to print either of those just does nothing if the mesh/shell is empty.
Group *g = SK.GetGroup(SK.groupOrder[SK.groupOrder.n - 1]); Group *g = SK.GetGroup(*SK.groupOrder.Last());
SMesh *m = &g->runningMesh; SMesh *m = &g->runningMesh;
for(i = 0; i < m->l.n; i++) { for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l[i]); STriangle *tr = &(m->l[i]);

View File

@ -383,7 +383,7 @@ void GraphicsWindow::Init() {
// And with the last group active // And with the last group active
ssassert(!SK.groupOrder.IsEmpty(), ssassert(!SK.groupOrder.IsEmpty(),
"Group order can't be empty since we will activate the last group."); "Group order can't be empty since we will activate the last group.");
activeGroup = SK.groupOrder[SK.groupOrder.n - 1]; activeGroup = *SK.groupOrder.Last();
SK.GetGroup(activeGroup)->Activate(); SK.GetGroup(activeGroup)->Activate();
showWorkplanes = false; showWorkplanes = false;

View File

@ -283,9 +283,7 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir) co
// Create a new empty contour in our polygon, and finish assembling // Create a new empty contour in our polygon, and finish assembling
// into that contour. // into that contour.
dest->AddEmptyContour(); dest->AddEmptyContour();
if(!AssembleContour(first, last, &(dest->l[dest->l.n-1]), if(!AssembleContour(first, last, dest->l.Last(), errorAt, keepDir)) {
errorAt, keepDir))
{
allClosed = false; allClosed = false;
} }
// But continue assembling, even if some of the contours are open // But continue assembling, even if some of the contours are open

View File

@ -293,16 +293,16 @@ void SSurface::FindChainAvoiding(SEdgeList *src, SEdgeList *dest,
{ {
ssassert(!src->l.IsEmpty(), "Need at least one edge"); ssassert(!src->l.IsEmpty(), "Need at least one edge");
// Start with an arbitrary edge. // Start with an arbitrary edge.
dest->l.Add(&(src->l[0])); dest->l.Add(src->l.First());
src->l.ClearTags(); src->l.ClearTags();
src->l[0].tag = 1; src->l.First()->tag = 1;
bool added; bool added;
do { do {
added = false; added = false;
// The start and finish of the current edge chain // The start and finish of the current edge chain
Vector s = dest->l[0].a, Vector s = dest->l.First()->a,
f = dest->l[dest->l.n - 1].b; f = dest->l.Last()->b;
// We can attach a new edge at the start or finish, as long as that // We can attach a new edge at the start or finish, as long as that
// start or finish point isn't in the list of points to avoid. // start or finish point isn't in the list of points to avoid.

View File

@ -470,15 +470,15 @@ void SBezierLoop::MakePwlInto(SContour *sc, double chordTol) const {
} }
} }
// Ensure that it's exactly closed, not just within a numerical tolerance. // Ensure that it's exactly closed, not just within a numerical tolerance.
if((sc->l[sc->l.n - 1].p).Equals(sc->l[0].p)) { if((sc->l.Last()->p).Equals(sc->l.First()->p)) {
sc->l[sc->l.n - 1] = sc->l[0]; *sc->l.Last() = *sc->l.First();
} }
} }
bool SBezierLoop::IsClosed() const { bool SBezierLoop::IsClosed() const {
if(l.n < 1) return false; if(l.n < 1) return false;
Vector s = l[0].Start(), Vector s = l.First()->Start(),
f = l[l.n-1].Finish(); f = l.Last()->Finish();
return s.Equals(f); return s.Equals(f);
} }
@ -512,7 +512,7 @@ SBezierLoopSet SBezierLoopSet::From(SBezierList *sbl, SPolygon *poly,
} else { } else {
ret.l.Add(&loop); ret.l.Add(&loop);
poly->AddEmptyContour(); poly->AddEmptyContour();
loop.MakePwlInto(&(poly->l[poly->l.n-1]), chordTol); loop.MakePwlInto(poly->l.Last(), chordTol);
} }
} }
@ -553,7 +553,7 @@ double SBezierLoopSet::SignedArea() {
void SBezierLoopSet::MakePwlInto(SPolygon *sp) const { void SBezierLoopSet::MakePwlInto(SPolygon *sp) const {
for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) { for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) {
sp->AddEmptyContour(); sp->AddEmptyContour();
sbl->MakePwlInto(&(sp->l[sp->l.n - 1])); sbl->MakePwlInto(sp->l.Last());
} }
} }
@ -618,7 +618,7 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
for(pt = sc->l.First(); pt; pt = sc->l.NextAfter(pt)) { for(pt = sc->l.First(); pt; pt = sc->l.NextAfter(pt)) {
double u, v; double u, v;
srfuv->ClosestPointTo(pt->p, &u, &v); srfuv->ClosestPointTo(pt->p, &u, &v);
spuv.l[spuv.l.n - 1].AddPoint(Vector::From(u, v, 0)); spuv.l.Last()->AddPoint(Vector::From(u, v, 0));
} }
} }
spuv.normal = Vector::From(0, 0, 1); // must be, since it's in xy plane now spuv.normal = Vector::From(0, 0, 1); // must be, since it's in xy plane now
@ -850,11 +850,11 @@ STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc, bool backwards) {
if(backwards) { if(backwards) {
stb.finish = sc->pts[0].p; stb.finish = sc->pts[0].p;
stb.start = sc->pts[sc->pts.n - 1].p; stb.start = sc->pts.Last()->p;
stb.backwards = true; stb.backwards = true;
} else { } else {
stb.start = sc->pts[0].p; stb.start = sc->pts[0].p;
stb.finish = sc->pts[sc->pts.n - 1].p; stb.finish = sc->pts.Last()->p;
stb.backwards = false; stb.backwards = false;
} }