Add and use IdList::IsEmpty. NFC.
Removes consuming code from the implementation details, easing swap of the underlying container, etc.
This commit is contained in:
parent
b5f36a4f01
commit
5ada4dbd9c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
16
src/dsc.h
16
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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)) {
|
||||
|
@ -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..."),
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 &&
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -1055,7 +1055,7 @@ void SShell::TriangulateInto(SMesh *sm) {
|
||||
}
|
||||
|
||||
bool SShell::IsEmpty() const {
|
||||
return (surface.n == 0);
|
||||
return surface.IsEmpty();
|
||||
}
|
||||
|
||||
void SShell::Clear() {
|
||||
|
@ -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 };
|
||||
|
Loading…
Reference in New Issue
Block a user