From 5ada4dbd9c5145103d6f067ae2d557a93edc01d7 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Wed, 3 Jan 2018 15:10:18 -0600 Subject: [PATCH] Add and use IdList::IsEmpty. NFC. Removes consuming code from the implementation details, easing swap of the underlying container, etc. --- src/clipboard.cpp | 2 +- src/draw.cpp | 3 ++- src/drawentity.cpp | 20 +++++++++----------- src/dsc.h | 16 +++++++++++++--- src/exportstep.cpp | 14 ++++++++------ src/file.cpp | 2 +- src/graphicswin.cpp | 2 +- src/group.cpp | 2 +- src/groupmesh.cpp | 8 +++++--- src/lib.cpp | 2 +- src/mesh.cpp | 4 +--- src/modify.cpp | 2 +- src/mouse.cpp | 2 +- src/polygon.cpp | 3 ++- src/render/render2d.cpp | 3 ++- src/render/rendergl3.cpp | 3 ++- src/solvespace.cpp | 4 ++-- src/srf/boolean.cpp | 10 +++++----- src/srf/curve.cpp | 4 ++-- src/srf/merge.cpp | 3 ++- src/srf/surface.cpp | 2 +- src/srf/surfinter.cpp | 3 ++- 22 files changed, 65 insertions(+), 49 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index 34d102c..011b658 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -287,7 +287,7 @@ void GraphicsWindow::MenuClipboard(Command id) { } case Command::PASTE_TRANSFORM: { - if(SS.clipboard.r.n == 0) { + if(SS.clipboard.r.IsEmpty()) { Error(_("Clipboard is empty; nothing to paste.")); break; } diff --git a/src/draw.cpp b/src/draw.cpp index 61a90f6..dc451fd 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -329,7 +329,8 @@ Lighting GraphicsWindow::GetLighting() const { GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() { Selection sel = {}; - if(hoverList.n == 0) return sel; + if(hoverList.IsEmpty()) + return sel; Group *activeGroup = SK.GetGroup(SS.GW.activeGroup); int bestOrder = -1; diff --git a/src/drawentity.cpp b/src/drawentity.cpp index ea53e9f..9232b42 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -34,18 +34,18 @@ void Entity::GenerateEdges(SEdgeList *el) { } SBezierList *Entity::GetOrGenerateBezierCurves() { - if(beziers.l.n == 0) + if(beziers.l.IsEmpty()) GenerateBezierCurves(&beziers); return &beziers; } SEdgeList *Entity::GetOrGenerateEdges() { - if(edges.l.n != 0) { + if(!edges.l.IsEmpty()) { if(EXACT(edgesChordTol == SS.ChordTolMm())) return &edges; edges.l.Clear(); } - if(edges.l.n == 0) + if(edges.l.IsEmpty()) GenerateEdges(&edges); edgesChordTol = SS.ChordTolMm(); return &edges; @@ -55,7 +55,7 @@ BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) { SBezierList *sbl = GetOrGenerateBezierCurves(); // We don't bother with bounding boxes for workplanes, etc. - *hasBBox = (IsPoint() || IsNormal() || sbl->l.n > 0); + *hasBBox = (IsPoint() || IsNormal() || !sbl->l.IsEmpty()); if(!*hasBBox) return {}; if(screenBBoxValid) @@ -67,16 +67,14 @@ BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) { } else if(IsNormal()) { Vector proj = SK.GetEntity(point[0])->PointGetNum(); screenBBox = BBox::From(proj, proj); - } else if(sbl->l.n > 0) { + } else if(!sbl->l.IsEmpty()) { Vector first = SS.GW.ProjectPoint3(sbl->l.elem[0].ctrl[0]); screenBBox = BBox::From(first, first); - for(int i = 0; i < sbl->l.n; i++) { - SBezier *sb = &sbl->l.elem[i]; - for(int i = 0; i <= sb->deg; i++) { - screenBBox.Include(SS.GW.ProjectPoint3(sb->ctrl[i])); - } + for(auto &sb : sbl->l) { + for(int i = 0; i < sb.deg; ++i) { screenBBox.Include(SS.GW.ProjectPoint3(sb.ctrl[i])); } } - } else ssassert(false, "Expected entity to be a point or have beziers"); + } else + ssassert(false, "Expected entity to be a point or have beziers"); screenBBoxValid = true; return screenBBox; diff --git a/src/dsc.h b/src/dsc.h index 656381a..3a62cee 100644 --- a/src/dsc.h +++ b/src/dsc.h @@ -325,8 +325,12 @@ public: int n; int elemsAllocated; + bool IsEmpty() const { + return n == 0; + } + uint32_t MaximumId() { - if(n == 0) { + if(IsEmpty()) { return 0; } else { return elem[n - 1].h.v; @@ -385,6 +389,9 @@ public: } int IndexOf(H h) { + if(IsEmpty()) { + return -1; + } int first = 0, last = n-1; while(first <= last) { int mid = (first + last)/2; @@ -401,6 +408,9 @@ public: } T *FindByIdNoOops(H h) { + if(IsEmpty()) { + return nullptr; + } int first = 0, last = n-1; while(first <= last) { int mid = (first + last)/2; @@ -417,10 +427,10 @@ public: } T *First() { - return (n == 0) ? NULL : &(elem[0]); + return (IsEmpty()) ? NULL : &(elem[0]); } T *NextAfter(T *prev) { - if(!prev) return NULL; + if(IsEmpty() || !prev) return NULL; if(prev - elem == (n - 1)) return NULL; return prev + 1; } diff --git a/src/exportstep.cpp b/src/exportstep.cpp index 970c925..9e42211 100644 --- a/src/exportstep.cpp +++ b/src/exportstep.cpp @@ -296,12 +296,13 @@ void StepFileWriter::ExportSurfacesTo(const Platform::Path &filename) { Group *g = SK.GetGroup(SS.GW.activeGroup); SShell *shell = &(g->runningShell); - if(shell->surface.n == 0) { + if(shell->surface.IsEmpty()) { Error("The model does not contain any surfaces to export.%s", - g->runningMesh.l.n > 0 ? - "\n\nThe model does contain triangles from a mesh, but " - "a triangle mesh cannot be exported as a STEP file. Try " - "File -> Export Mesh... instead." : ""); + !g->runningMesh.l.IsEmpty() + ? "\n\nThe model does contain triangles from a mesh, but " + "a triangle mesh cannot be exported as a STEP file. Try " + "File -> Export Mesh... instead." + : ""); return; } @@ -318,7 +319,8 @@ void StepFileWriter::ExportSurfacesTo(const Platform::Path &filename) { SSurface *ss; for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) { - if(ss->trim.n == 0) continue; + 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 diff --git a/src/file.cpp b/src/file.cpp index cd9d1ec..bc98d75 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -549,7 +549,7 @@ bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel) Error(_("Unrecognized data in file. This file may be corrupt, or " "from a newer version of the program.")); // At least leave the program in a non-crashing state. - if(SK.group.n == 0) { + if(SK.group.IsEmpty()) { NewFile(); } } diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp index 921abfe..695a51c 100644 --- a/src/graphicswin.cpp +++ b/src/graphicswin.cpp @@ -1306,7 +1306,7 @@ void GraphicsWindow::ToggleBool(bool *v) { // If the mesh or edges were previously hidden, they haven't been generated, // and if we are going to show them, we need to generate them first. Group *g = SK.GetGroup(SS.GW.activeGroup); - if(*v && (g->displayOutlines.l.n == 0 && (v == &showEdges || v == &showOutlines))) { + if(*v && (g->displayOutlines.l.IsEmpty() && (v == &showEdges || v == &showOutlines))) { SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE); } diff --git a/src/group.cpp b/src/group.cpp index ec8385b..3779c69 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -297,7 +297,7 @@ void Group::MenuGroup(Command id, Platform::Path linkFile) { } // Copy color from the previous mesh-contributing group. - if(g.IsMeshGroup() && SK.groupOrder.n > 0) { + if(g.IsMeshGroup() && !SK.groupOrder.IsEmpty()) { Group *running = SK.GetRunningMeshGroupFor(SS.GW.activeGroup); if(running != NULL) { g.color = running->color; diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index 56899b7..61ddfd2 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -466,7 +466,7 @@ void Group::GenerateDisplayItems() { if(SS.GW.showEdges || SS.GW.showOutlines) { SOutlineList rawOutlines = {}; - if(runningMesh.l.n > 0) { + if(!runningMesh.l.IsEmpty()) { // Triangle mesh only; no shell or emphasized edges. runningMesh.MakeOutlinesInto(&rawOutlines, EdgeKind::EMPHASIZED); } else { @@ -706,7 +706,8 @@ void Group::DrawPolyError(Canvas *canvas) { void Group::DrawFilledPaths(Canvas *canvas) { for(const SBezierLoopSet &sbls : bezierLoops.l) { - if(sbls.l.n == 0 || sbls.l.elem[0].l.n == 0) continue; + if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty()) + continue; // In an assembled loop, all the styles should be the same; so doesn't // matter which one we grab. @@ -740,7 +741,8 @@ void Group::DrawContourAreaLabels(Canvas *canvas) { Vector gu = camera.projUp.ScaledBy(1 / camera.scale); for(SBezierLoopSet &sbls : bezierLoops.l) { - if(sbls.l.n == 0 || sbls.l.elem[0].l.n == 0) continue; + if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty()) + continue; Vector min = sbls.l.elem[0].l.elem[0].ctrl[0]; Vector max = min; diff --git a/src/lib.cpp b/src/lib.cpp index a800924..5b95545 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -182,7 +182,7 @@ default: dbp("bad constraint type %d", sc->type); return; c.other2 = (sc->other2) ? true : false; c.Generate(¶ms); - if(params.n > 0) { + if(!params.IsEmpty()) { for(Param &p : params) { p.h = SK.param.AddAndAssignId(&p); c.valP = p.h; diff --git a/src/mesh.cpp b/src/mesh.cpp index 52f8c0b..d3aaa63 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -318,9 +318,7 @@ void SMesh::MakeFromTransformationOf(SMesh *a, Vector trans, } } -bool SMesh::IsEmpty() const { - return (l.n == 0); -} +bool SMesh::IsEmpty() const { return (l.IsEmpty()); } uint32_t SMesh::FirstIntersectionWith(Point2d mp) const { Vector rayPoint = SS.GW.UnProjectPoint3(Vector::From(mp.x, mp.y, 0.0)); diff --git a/src/modify.cpp b/src/modify.cpp index e060700..cfd7c15 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -682,7 +682,7 @@ void GraphicsWindow::SplitLinesOrCurves() { sbla.AllIntersectionsWith(&sblb, &inters); // If there's multiple points, then take the one closest to the mouse pointer. - if(inters.l.n > 0) { + if(!inters.l.IsEmpty()) { double dmin = VERY_POSITIVE; SPoint *sp; for(sp = inters.l.First(); sp; sp = inters.l.NextAfter(sp)) { diff --git a/src/mouse.cpp b/src/mouse.cpp index f0a8c6c..0e101a7 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -755,7 +755,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) { [&]() { MenuEdit(Command::SELECT_ALL); }); } - if((SS.clipboard.r.n > 0 || SS.clipboard.c.n > 0) && LockedInWorkplane()) { + if((!SS.clipboard.r.IsEmpty() || !SS.clipboard.c.IsEmpty()) && LockedInWorkplane()) { menu->AddItem(_("Paste"), [&]() { MenuClipboard(Command::PASTE); }); menu->AddItem(_("Paste Transformed..."), diff --git a/src/polygon.cpp b/src/polygon.cpp index f6ec6a2..34641cd 100644 --- a/src/polygon.cpp +++ b/src/polygon.cpp @@ -752,7 +752,8 @@ void SPolygon::FixContourDirections() { } bool SPolygon::IsEmpty() const { - if(l.n == 0 || l.elem[0].l.n == 0) return true; + if(l.IsEmpty() || l[0].l.IsEmpty()) + return true; return false; } diff --git a/src/render/render2d.cpp b/src/render/render2d.cpp index 9a8995c..f03c284 100644 --- a/src/render/render2d.cpp +++ b/src/render/render2d.cpp @@ -255,7 +255,8 @@ void SurfaceRenderer::ConvertBeziersToEdges() { void SurfaceRenderer::CullOccludedStrokes() { // Perform occlusion testing, if necessary. - if(mesh.l.n == 0) return; + if(mesh.l.IsEmpty()) + return; // We can't perform hidden line removal on exact curves. ConvertBeziersToEdges(); diff --git a/src/render/rendergl3.cpp b/src/render/rendergl3.cpp index 3b00241..58f41eb 100644 --- a/src/render/rendergl3.cpp +++ b/src/render/rendergl3.cpp @@ -458,7 +458,8 @@ void OpenGl3Renderer::DrawEdges(const SEdgeList &el, hStroke hcs) { } void OpenGl3Renderer::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs mode) { - if(ol.l.n == 0) return; + if(ol.l.IsEmpty()) + return; Stroke *stroke = SelectStroke(hcs); ssassert(stroke->stipplePattern != StipplePattern::ZIGZAG && diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 82daaa1..89ea71c 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -938,7 +938,7 @@ void SolveSpaceUI::ShowNakedEdges(bool reportOnlyWhenNotOkay) { root->MakeCertainEdgesInto(&(SS.nakedEdges), EdgeKind::NAKED_OR_SELF_INTER, /*coplanarIsInter=*/true, &inters, &leaks); - if(reportOnlyWhenNotOkay && !inters && !leaks && SS.nakedEdges.l.n == 0) { + if(reportOnlyWhenNotOkay && !inters && !leaks && SS.nakedEdges.l.IsEmpty()) { return; } SS.GW.Invalidate(); @@ -954,7 +954,7 @@ void SolveSpaceUI::ShowNakedEdges(bool reportOnlyWhenNotOkay) { _("\n\nThe model contains %d triangles, from %d surfaces."), g->displayMesh.l.n, g->runningShell.surface.n); - if(SS.nakedEdges.l.n == 0) { + if(SS.nakedEdges.l.IsEmpty()) { Message(_("%s\n\n%s\n\nZero problematic edges, good.%s"), intersMsg, leaksMsg, cntMsg.c_str()); } else { diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp index 7508116..ad8002a 100644 --- a/src/srf/boolean.cpp +++ b/src/srf/boolean.cpp @@ -59,7 +59,7 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, agnstB->AllPointsIntersecting(prev.p, p->p, &il, /*asSegment=*/true, /*trimmed=*/false, /*inclTangent=*/true); - if(il.n > 0) { + if(!il.IsEmpty()) { // The intersections were generated by intersecting the pwl // edge against a surface; so they must be refined to lie // exactly on the original curve. @@ -297,7 +297,7 @@ static void DEBUGEDGELIST(SEdgeList *sel, SSurface *surf) { void SSurface::FindChainAvoiding(SEdgeList *src, SEdgeList *dest, SPointList *avoid) { - ssassert(src->l.n > 0, "Need at least one edge"); + ssassert(!src->l.IsEmpty(), "Need at least one edge"); // Start with an arbitrary edge. dest->l.Add(&(src->l.elem[0])); src->l.ClearTags(); @@ -512,7 +512,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent, // our original and intersecting edge lists. SEdgeList final = {}; - while(orig.l.n > 0) { + while(!orig.l.IsEmpty()) { SEdgeList chain = {}; FindChainAvoiding(&orig, &chain, &choosing); @@ -546,7 +546,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent, chain.Clear(); } - while(inter.l.n > 0) { + while(!inter.l.IsEmpty()) { SEdgeList chain = {}; FindChainAvoiding(&inter, &chain, &choosing); @@ -731,7 +731,7 @@ void SShell::MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type) { a->MakeClassifyingBsps(this); b->MakeClassifyingBsps(this); - if(b->surface.n == 0 || a->surface.n == 0) { + if(b->surface.IsEmpty() || a->surface.IsEmpty()) { I = 1000000; } else { I = 0; diff --git a/src/srf/curve.cpp b/src/srf/curve.cpp index ef30dd5..dca07fc 100644 --- a/src/srf/curve.cpp +++ b/src/srf/curve.cpp @@ -311,7 +311,7 @@ bool SBezierList::GetPlaneContainingBeziers(Vector *p, Vector *u, Vector *v, int i; // Get any point on any Bezier; or an arbitrary point if list is empty. - if(l.n > 0) { + if(!l.IsEmpty()) { pt = l.elem[0].Start(); } else { pt = Vector::From(0, 0, 0); @@ -402,7 +402,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl, sbl->l.RemoveTagged(); - while(sbl->l.n > 0 && !hanging.Equals(start)) { + while(!sbl->l.IsEmpty() && !hanging.Equals(start)) { int i; bool foundNext = false; for(i = 0; i < sbl->l.n; i++) { diff --git a/src/srf/merge.cpp b/src/srf/merge.cpp index ed3034f..f00a6f2 100644 --- a/src/srf/merge.cpp +++ b/src/srf/merge.cpp @@ -17,7 +17,8 @@ void SShell::MergeCoincidentSurfaces() { if(si->tag) continue; // Let someone else clean up the empty surfaces; we can certainly merge // them, but we don't know how to calculate a reasonable bounding box. - if(si->trim.n == 0) continue; + if(si->trim.IsEmpty()) + continue; // And for now we handle only coincident planes, so no sense wasting // time on other surfaces. if(si->degm != 1 || si->degn != 1) continue; diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp index a6f7ac3..e147fe6 100644 --- a/src/srf/surface.cpp +++ b/src/srf/surface.cpp @@ -1055,7 +1055,7 @@ void SShell::TriangulateInto(SMesh *sm) { } bool SShell::IsEmpty() const { - return (surface.n == 0); + return surface.IsEmpty(); } void SShell::Clear() { diff --git a/src/srf/surfinter.cpp b/src/srf/surfinter.cpp index a64f884..554c149 100644 --- a/src/srf/surfinter.cpp +++ b/src/srf/surfinter.cpp @@ -326,7 +326,8 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, srfB->AllPointsIntersecting(se->a, se->b, &lsi, /*asSegment=*/true, /*trimmed=*/true, /*inclTangent=*/false); - if(lsi.n == 0) continue; + if(lsi.IsEmpty()) + continue; // Find the other surface that this curve trims. hSCurve hsc = { (uint32_t)se->auxA };