Improve implementation hiding in IdList/List. NFC.

Allows distancing users from the internal "elem" member.

Add Get() and operator[].
Replace direct references to elem.
Make elem and elemsAllocated private in IdList/List.
pull/459/head
Ryan Pavlik 2019-05-23 12:09:47 -05:00 committed by whitequark
parent 482f0e8de9
commit 0bfbbe2bf3
32 changed files with 220 additions and 207 deletions

View File

@ -20,7 +20,7 @@ SBsp3 *SBsp3::FromMesh(const SMesh *m) {
while(n > 1) {
int k = rand() % n;
n--;
swap(mc.l.elem[k], mc.l.elem[n]);
swap(mc.l[k], mc.l[n]);
}
SBsp3 *bsp3 = NULL;

View File

@ -172,7 +172,7 @@ void ConstraintBase::ModifyToSatisfy() {
// These equations are written in the form f(...) - d = 0, where
// d is the value of the valA.
valA += (l.elem[0].e)->Eval();
valA += (l[0].e)->Eval();
l.Clear();
}

View File

@ -35,7 +35,7 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
if(!r) return;
SS.UndoRemember();
r->font = SS.fonts.l.elem[i].FontFileBaseName();
r->font = SS.fonts.l[i].FontFileBaseName();
SS.MarkGroupDirty(r->group);
SS.ScheduleShowTW();
}
@ -177,7 +177,7 @@ void TextWindow::DescribeSelection() {
SS.fonts.LoadAll();
int i;
for(i = 0; i < SS.fonts.l.n; i++) {
TtfFont *tf = &(SS.fonts.l.elem[i]);
TtfFont *tf = &(SS.fonts.l[i]);
if(e->font == tf->FontFileBaseName()) {
Printf(false, "%Bp %s",
(i & 1) ? 'd' : 'a',

View File

@ -233,7 +233,7 @@ void GraphicsWindow::GroupSelection() {
gs = {};
int i;
for(i = 0; i < selection.n; i++) {
Selection *s = &(selection.elem[i]);
Selection *s = &(selection[i]);
if(s->entity.v) {
(gs.n)++;

View File

@ -22,12 +22,12 @@ void Entity::GenerateEdges(SEdgeList *el) {
int i, j;
for(i = 0; i < sbl->l.n; i++) {
SBezier *sb = &(sbl->l.elem[i]);
SBezier *sb = &(sbl->l[i]);
List<Vector> lv = {};
sb->MakePwlInto(&lv);
for(j = 1; j < lv.n; j++) {
el->AddEdge(lv.elem[j-1], lv.elem[j], style.v, i);
el->AddEdge(lv[j-1], lv[j], style.v, i);
}
lv.Clear();
}
@ -68,7 +68,7 @@ BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) {
Vector proj = SK.GetEntity(point[0])->PointGetNum();
screenBBox = BBox::From(proj, proj);
} else if(!sbl->l.IsEmpty()) {
Vector first = SS.GW.ProjectPoint3(sbl->l.elem[0].ctrl[0]);
Vector first = SS.GW.ProjectPoint3(sbl->l[0].ctrl[0]);
screenBBox = BBox::From(first, first);
for(auto &sb : sbl->l) {
for(int i = 0; i < sb.deg; ++i) { screenBBox.Include(SS.GW.ProjectPoint3(sb.ctrl[i])); }
@ -439,7 +439,7 @@ void Entity::GenerateBezierCurves(SBezierList *sbl) const {
// Record our style for all of the Beziers that we just created.
for(; i < sbl->l.n; i++) {
sbl->l.elem[i].auxA = style.v;
sbl->l[i].auxA = style.v;
}
}

View File

@ -204,11 +204,12 @@ public:
// A simple list
template<class T>
class List {
public:
T *elem = nullptr;
int n = 0;
int elemsAllocated = 0;
public:
int n = 0;
bool IsEmpty() const { return n == 0; }
void ReserveMore(int howMuch) {
@ -260,6 +261,11 @@ public:
return prev + 1;
}
T &Get(size_t i) { return elem[i]; }
T const &Get(size_t i) const { return elem[i]; }
T &operator[](size_t i) { return Get(i); }
T const &operator[](size_t i) const { return Get(i); }
T *begin() { return IsEmpty() ? nullptr : &elem[0]; }
T *end() { return IsEmpty() ? nullptr : &elem[n]; }
const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; }
@ -331,10 +337,10 @@ struct CompareId {
// id.
template <class T, class H>
class IdList {
T *elem = nullptr;
int elemsAllocated = 0;
public:
T *elem;
int n;
int elemsAllocated;
int n = 0;
using Compare = CompareId<T, H>;
@ -450,6 +456,11 @@ public:
return prev + 1;
}
T &Get(size_t i) { return elem[i]; }
T const &Get(size_t i) const { return elem[i]; }
T &operator[](size_t i) { return Get(i); }
T const &operator[](size_t i) const { return Get(i); }
T *begin() { return IsEmpty() ? nullptr : &elem[0]; }
T *end() { return IsEmpty() ? nullptr : &elem[n]; }
const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; }

View File

@ -455,7 +455,7 @@ void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *s
// segments with zero-length projections.
sel->l.ClearTags();
for(int i = 0; i < sel->l.n; ++i) {
SEdge *sei = &sel->l.elem[i];
SEdge *sei = &sel->l[i];
hStyle hsi = { (uint32_t)sei->auxA };
Style *si = Style::Get(hsi);
if(sei->tag != 0) continue;
@ -472,7 +472,7 @@ void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *s
}
for(int j = i + 1; j < sel->l.n; ++j) {
SEdge *sej = &sel->l.elem[j];
SEdge *sej = &sel->l[j];
if(sej->tag != 0) continue;
Vector *pAj = &sej->a;
@ -761,7 +761,7 @@ void VectorFileWriter::BezierAsPwl(SBezier *sb) {
sb->MakePwlInto(&lv, SS.ExportChordTolMm());
int i;
for(i = 1; i < lv.n; i++) {
SBezier sb = SBezier::From(lv.elem[i-1], lv.elem[i]);
SBezier sb = SBezier::From(lv[i-1], lv[i]);
Bezier(&sb);
}
lv.Clear();
@ -875,7 +875,7 @@ void SolveSpaceUI::ExportMeshAsStlTo(FILE *f, SMesh *sm) {
double s = SS.exportScale;
int i;
for(i = 0; i < sm->l.n; i++) {
STriangle *tr = &(sm->l.elem[i]);
STriangle *tr = &(sm->l[i]);
Vector n = tr->Normal().WithMagnitude(1);
float w;
w = (float)n.x; fwrite(&w, 4, 1, f);
@ -981,7 +981,7 @@ void SolveSpaceUI::ExportMeshAsObjTo(FILE *fObj, FILE *fMtl, SMesh *sm) {
RgbaColor currentColor = {};
for(int i = 0; i < sm->l.n; i++) {
const STriangle &t = sm->l.elem[i];
const STriangle &t = sm->l[i];
if(!currentColor.Equals(t.meta.color)) {
currentColor = t.meta.color;
fprintf(fObj, "usemtl %s\n", colors[currentColor].c_str());

View File

@ -121,7 +121,7 @@ int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) {
List<int> listOfTrims = {};
SBezier *sb = &(loop->l.elem[loop->l.n - 1]);
SBezier *sb = &(loop->l[loop->l.n - 1]);
// 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

View File

@ -370,7 +370,7 @@ public:
DRW_Polyline polyline;
assignEntityDefaults(&polyline, hs);
for(int i = 0; i < lv.n; i++) {
Vector *v = &lv.elem[i];
Vector *v = &lv[i];
DRW_Vertex *vertex = new DRW_Vertex(v->x, v->y, v->z, 0.0);
polyline.vertlist.push_back(vertex);
}

View File

@ -343,10 +343,10 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
// 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.
Group *g = SK.GetGroup(SK.groupOrder.elem[SK.groupOrder.n - 1]);
Group *g = SK.GetGroup(SK.groupOrder[SK.groupOrder.n - 1]);
SMesh *m = &g->runningMesh;
for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
STriangle *tr = &(m->l[i]);
fprintf(fh, "Triangle %08x %08x "
"%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n",
tr->meta.face, tr->meta.color.ToPackedInt(),

View File

@ -149,7 +149,7 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
// Start from the first dirty group, and solve until the active group,
// since all groups after the active group are hidden.
for(i = 0; i < SK.groupOrder.n; i++) {
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
Group *g = SK.GetGroup(SK.groupOrder[i]);
if((!g->clean) || !g->IsSolvedOkay()) {
first = min(first, i);
}
@ -179,7 +179,7 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
case Generate::UNTIL_ACTIVE: {
for(i = 0; i < SK.groupOrder.n; i++) {
if(SK.groupOrder.elem[i] == SS.GW.activeGroup)
if(SK.groupOrder[i] == SS.GW.activeGroup)
break;
}
@ -214,7 +214,7 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
SK.entity.ReserveMore(oldEntityCount);
for(i = 0; i < SK.groupOrder.n; i++) {
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
Group *g = SK.GetGroup(SK.groupOrder[i]);
// The group may depend on entities or other groups, to define its
// workplane geometry or for its operands. Those must already exist
@ -423,7 +423,7 @@ void SolveSpaceUI::MarkDraggedParams() {
if(i == -1) {
hp = SS.GW.pending.point;
} else {
hp = SS.GW.pending.points.elem[i];
hp = SS.GW.pending.points[i];
}
if(!hp.v) continue;
@ -552,7 +552,7 @@ SolveResult SolveSpaceUI::TestRankForGroup(hGroup hg, int *rank) {
bool SolveSpaceUI::ActiveGroupsOkay() {
for(int i = 0; i < SK.groupOrder.n; i++) {
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
Group *g = SK.GetGroup(SK.groupOrder[i]);
if(!g->IsSolvedOkay())
return false;
if(g->h == SS.GW.activeGroup)

View File

@ -575,7 +575,7 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
Group *g = SK.GetGroup(activeGroup);
g->GenerateDisplayItems();
for(int i = 0; i < g->displayMesh.l.n; i++) {
STriangle *tr = &(g->displayMesh.l.elem[i]);
STriangle *tr = &(g->displayMesh.l[i]);
if(!includeMesh) {
bool found = false;
for(const hEntity &face : faces) {
@ -591,9 +591,9 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
}
if(!includeMesh) return;
for(int i = 0; i < g->polyLoops.l.n; i++) {
SContour *sc = &(g->polyLoops.l.elem[i]);
SContour *sc = &(g->polyLoops.l[i]);
for(int j = 0; j < sc->l.n; j++) {
HandlePointForZoomToFit(sc->l.elem[j].p, pmax, pmin, wmin, usePerspective, camera);
HandlePointForZoomToFit(sc->l[j].p, pmax, pmin, wmin, usePerspective, camera);
}
}
}
@ -610,7 +610,7 @@ double GraphicsWindow::ZoomToFit(const Camera &camera,
if(useSelection) {
for(int i = 0; i < selection.n; i++) {
Selection *s = &selection.elem[i];
Selection *s = &selection[i];
if(s->entity.v != 0) {
Entity *e = SK.entity.FindById(s->entity);
if(e->IsFace()) {
@ -851,7 +851,7 @@ void GraphicsWindow::EnsureValidActives() {
if((!g) || (g->h == Group::HGROUP_REFERENCES)) {
int i;
for(i = 0; i < SK.groupOrder.n; i++) {
if(SK.groupOrder.elem[i] != Group::HGROUP_REFERENCES) {
if(SK.groupOrder[i] != Group::HGROUP_REFERENCES) {
break;
}
}
@ -867,7 +867,7 @@ void GraphicsWindow::EnsureValidActives() {
// do it now so that drawing mode isn't switched to "Free in 3d".
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
} else {
activeGroup = SK.groupOrder.elem[i];
activeGroup = SK.groupOrder[i];
}
SK.GetGroup(activeGroup)->Activate();
change = true;

View File

@ -474,7 +474,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
hEntity pt = { 0 };
// Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]);
Entity *e = &(entity->Get(i));
if(e->group != opA) continue;
if(e->IsPoint()) pt = e->h;
@ -508,7 +508,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
// Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]);
Entity *e = &(entity->Get(i));
if(e->group != opA) continue;
e->CalculateNumerical(/*forExport=*/false);
@ -556,7 +556,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
int ai = 1;
for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]);
Entity *e = &((*entity)[i]);
if(e->group != opA)
continue;
@ -605,7 +605,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
int ai = 1;
for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]);
Entity *e = &(entity->Get(i));
if(e->group.v != opA.v)
continue;
@ -660,7 +660,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
for(a = a0; a < n; a++) {
// Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]);
Entity *e = &(entity->Get(i));
if(e->group != opA) continue;
e->CalculateNumerical(/*forExport=*/false);
@ -696,7 +696,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
for(a = a0; a < n; a++) {
// Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < entity->n; i++) {
Entity *e = &(entity->elem[i]);
Entity *e = &(entity->Get(i));
if(e->group != opA) continue;
e->CalculateNumerical(/*forExport=*/false);
@ -723,7 +723,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
// Not using range-for here because we're changing the size of entity in the loop.
for(i = 0; i < impEntity.n; i++) {
Entity *ie = &(impEntity.elem[i]);
Entity *ie = &(impEntity[i]);
CopyEntity(entity, ie, 0, 0,
h.param(0), h.param(1), h.param(2),
h.param(3), h.param(4), h.param(5), h.param(6), NO_PARAM,

View File

@ -240,7 +240,7 @@ void Group::GenerateShellAndMesh() {
// Not using range-for here because we're starting at a different place and using
// indices for meaning.
for(i = is; i < thisShell.surface.n; i++) {
SSurface *ss = &(thisShell.surface.elem[i]);
SSurface *ss = &(thisShell.surface[i]);
hEntity face = Entity::NO_ENTITY;
Vector p = ss->PointAt(0, 0),
@ -711,7 +711,7 @@ void Group::DrawFilledPaths(Canvas *canvas) {
// In an assembled loop, all the styles should be the same; so doesn't
// matter which one we grab.
SBezier *sb = &(sbls.l.elem[0].l.elem[0]);
const SBezier *sb = &(sbls.l[0].l[0]);
Style *s = Style::Get({ (uint32_t)sb->auxA });
Canvas::Fill fill = {};
@ -744,7 +744,7 @@ void Group::DrawContourAreaLabels(Canvas *canvas) {
if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty())
continue;
Vector min = sbls.l.elem[0].l.elem[0].ctrl[0];
Vector min = sbls.l[0].l[0].ctrl[0];
Vector max = min;
Vector zero = Vector::From(0.0, 0.0, 0.0);
sbls.GetBoundingProjd(Vector::From(1.0, 0.0, 0.0), zero, &min.x, &max.x);

View File

@ -240,7 +240,7 @@ default: dbp("bad constraint type %d", sc->type); return;
if(ssys->failed) {
// Copy over any the list of problematic constraints.
for(i = 0; i < ssys->faileds && i < bad.n; i++) {
ssys->failed[i] = bad.elem[i].v;
ssys->failed[i] = bad[i].v;
}
ssys->faileds = bad.n;
}

View File

@ -51,7 +51,7 @@ void SMesh::GetBounding(Vector *vmax, Vector *vmin) const {
*vmin = Vector::From( 1e12, 1e12, 1e12);
*vmax = Vector::From(-1e12, -1e12, -1e12);
for(i = 0; i < l.n; i++) {
STriangle *st = &(l.elem[i]);
const STriangle *st = &(l[i]);
DoBounding(st->a, vmax, vmin);
DoBounding(st->b, vmax, vmin);
DoBounding(st->c, vmax, vmin);
@ -70,7 +70,7 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
m.l.ClearTags();
int i;
for(i = 0; i < m.l.n; i++) {
STriangle *tr = &(m.l.elem[i]);
STriangle *tr = &(m.l[i]);
if((fabs(n.Dot(tr->a) - d) >= LENGTH_EPS) ||
(fabs(n.Dot(tr->b) - d) >= LENGTH_EPS) ||
@ -96,7 +96,7 @@ void SMesh::MakeOutlinesInto(SOutlineList *sol, EdgeKind edgeKind) {
}
//-----------------------------------------------------------------------------
// When we are called, all of the triangles from l.elem[start] to the end must
// When we are called, all of the triangles from l[start] to the end must
// be coplanar. So we try to find a set of fewer triangles that covers the
// exact same area, in order to reduce the number of triangles in the mesh.
// We use this after a triangle has been split against the BSP.
@ -108,7 +108,7 @@ void SMesh::MakeOutlinesInto(SOutlineList *sol, EdgeKind edgeKind) {
void SMesh::Simplify(int start) {
int maxTriangles = (l.n - start) + 10;
STriMeta meta = l.elem[start].meta;
STriMeta meta = l[start].meta;
STriangle *tout = (STriangle *)MemAlloc(maxTriangles*sizeof(*tout));
int toutc = 0;
@ -121,7 +121,7 @@ void SMesh::Simplify(int start) {
int i, j;
for(i = start; i < l.n; i++) {
STriangle *tr = &(l.elem[i]);
STriangle *tr = &(l[i]);
if(tr->MinAltitude() < LENGTH_EPS) {
tr->tag = 1;
} else {
@ -133,7 +133,7 @@ void SMesh::Simplify(int start) {
bool didAdd;
convc = 0;
for(i = start; i < l.n; i++) {
STriangle *tr = &(l.elem[i]);
STriangle *tr = &(l[i]);
if(tr->tag) continue;
tr->tag = 1;
@ -158,7 +158,7 @@ void SMesh::Simplify(int start) {
Vector c;
for(i = start; i < l.n; i++) {
STriangle *tr = &(l.elem[i]);
STriangle *tr = &(l[i]);
if(tr->tag) continue;
if((tr->a).Equals(d) && (tr->b).Equals(b)) {
@ -242,7 +242,7 @@ void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) {
int i;
for(i = 0; i < srcm->l.n; i++) {
STriangle *st = &(srcm->l.elem[i]);
STriangle *st = &(srcm->l[i]);
int pn = l.n;
atLeastOneDiscarded = false;
SBsp3::InsertOrCreate(bsp3, st, this);
@ -289,7 +289,7 @@ void SMesh::MakeFromDifferenceOf(SMesh *a, SMesh *b) {
void SMesh::MakeFromCopyOf(SMesh *a) {
ssassert(this != a, "Can't make from copy of self");
for(int i = 0; i < a->l.n; i++) {
AddTriangle(&(a->l.elem[i]));
AddTriangle(&(a->l[i]));
}
}
@ -327,7 +327,7 @@ uint32_t SMesh::FirstIntersectionWith(Point2d mp) const {
uint32_t face = 0;
double faceT = VERY_NEGATIVE;
for(int i = 0; i < l.n; i++) {
const STriangle &tr = l.elem[i];
const STriangle &tr = l[i];
if(tr.meta.face == 0) continue;
double t;
@ -345,7 +345,7 @@ Vector SMesh::GetCenterOfMass() const {
Vector center = {};
double vol = 0.0;
for(int i = 0; i < l.n; i++) {
STriangle &tr = l.elem[i];
const STriangle &tr = l[i];
double tvol = tr.SignedVolume();
center = center.Plus(tr.a.Plus(tr.b.Plus(tr.c)).ScaledBy(tvol / 4.0));
vol += tvol;
@ -363,7 +363,7 @@ SKdNode *SKdNode::From(SMesh *m) {
STriangle *tra = (STriangle *)AllocTemporary((m->l.n) * sizeof(*tra));
for(i = 0; i < m->l.n; i++) {
tra[i] = m->l.elem[i];
tra[i] = m->l[i];
}
srand(0);
@ -635,7 +635,7 @@ void SKdNode::SnapToVertex(Vector v, SMesh *extras) {
void SKdNode::SnapToMesh(SMesh *m) {
int i, j, k;
for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
STriangle *tr = &(m->l[i]);
if(tr->IsDegenerate()) {
continue;
}
@ -647,7 +647,7 @@ void SKdNode::SnapToMesh(SMesh *m) {
for(k = 0; k < extra.l.n; k++) {
STriangle *tra = (STriangle *)AllocTemporary(sizeof(*tra));
*tra = extra.l.elem[k];
*tra = extra.l[k];
AddTriangle(tra);
}
extra.Clear();

View File

@ -98,7 +98,7 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
// that relationship. So put it back here now.
int i;
for(i = 1; i < ld.n; i++) {
Constraint::ConstrainCoincident(ld.elem[i-1], ld.elem[i]);
Constraint::ConstrainCoincident(ld[i-1], ld[i]);
}
ld.Clear();
}
@ -410,7 +410,7 @@ void GraphicsWindow::MakeTangentArc() {
// Delete the coincident constraint for the removed point.
SK.constraint.ClearTags();
for(i = 0; i < SK.constraint.n; i++) {
Constraint *cs = &(SK.constraint.elem[i]);
Constraint *cs = &(SK.constraint[i]);
if(cs->group != activeGroup) continue;
if(cs->workplane != ActiveWorkplane()) continue;
if(cs->type != Constraint::Type::POINTS_COINCIDENT) continue;
@ -535,7 +535,7 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
double t;
int i, j;
for(i = 0; i < sbl.l.n; i++) {
SBezier *sb = &(sbl.l.elem[i]);
SBezier *sb = &(sbl.l[i]);
ssassert(sb->deg == 3, "Expected a cubic bezier");
sb->ClosestPointTo(pinter, &t, /*mustConverge=*/false);

View File

@ -227,7 +227,8 @@ bool SEdgeList::AssembleContour(Vector first, Vector last, SContour *dest,
do {
for(i = 0; i < l.n; i++) {
SEdge *se = &(l.elem[i]);
/// @todo fix const!
SEdge *se = const_cast<SEdge*>(&(l[i]));
if(se->tag) continue;
if(se->a.Equals(last)) {
@ -267,10 +268,11 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir) co
Vector last = Vector::From(0, 0, 0);
int i;
for(i = 0; i < l.n; i++) {
if(!l.elem[i].tag) {
first = l.elem[i].a;
last = l.elem[i].b;
l.elem[i].tag = 1;
if(!l[i].tag) {
first = l[i].a;
last = l[i].b;
/// @todo fix const!
const_cast<SEdge*>(&(l[i]))->tag = 1;
break;
}
}
@ -281,7 +283,7 @@ bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir) co
// Create a new empty contour in our polygon, and finish assembling
// into that contour.
dest->AddEmptyContour();
if(!AssembleContour(first, last, &(dest->l.elem[dest->l.n-1]),
if(!AssembleContour(first, last, &(dest->l[dest->l.n-1]),
errorAt, keepDir))
{
allClosed = false;
@ -337,9 +339,9 @@ void SEdgeList::CullExtraneousEdges(bool both) {
l.ClearTags();
int i, j;
for(i = 0; i < l.n; i++) {
SEdge *se = &(l.elem[i]);
SEdge *se = &(l[i]);
for(j = i+1; j < l.n; j++) {
SEdge *set = &(l.elem[j]);
SEdge *set = &(l[j]);
if((set->a).Equals(se->a) && (set->b).Equals(se->b)) {
// Two parallel edges exist; so keep only the first one.
set->tag = 1;
@ -527,7 +529,7 @@ bool SPointList::ContainsPoint(Vector pt) const {
int SPointList::IndexForPoint(Vector pt) const {
int i;
for(i = 0; i < l.n; i++) {
SPoint *p = &(l.elem[i]);
const SPoint *p = &(l[i]);
if(pt.Equals(p->p)) {
return i;
}
@ -567,7 +569,7 @@ void SContour::AddPoint(Vector p) {
void SContour::MakeEdgesInto(SEdgeList *el) const {
int i;
for(i = 0; i < (l.n - 1); i++) {
el->AddEdge(l.elem[i].p, l.elem[i+1].p);
el->AddEdge(l[i].p, l[i+1].p);
}
}
@ -590,8 +592,8 @@ Vector SContour::ComputeNormal() const {
Vector n = Vector::From(0, 0, 0);
for(int i = 0; i < l.n - 2; i++) {
Vector u = (l.elem[i+1].p).Minus(l.elem[i+0].p).WithMagnitude(1);
Vector v = (l.elem[i+2].p).Minus(l.elem[i+1].p).WithMagnitude(1);
Vector u = (l[i+1].p).Minus(l[i+0].p).WithMagnitude(1);
Vector v = (l[i+2].p).Minus(l[i+1].p).WithMagnitude(1);
Vector nt = u.Cross(v);
if(nt.Magnitude() > n.Magnitude()) {
n = nt;
@ -602,7 +604,7 @@ Vector SContour::ComputeNormal() const {
Vector SContour::AnyEdgeMidpoint() const {
ssassert(l.n >= 2, "Need two points to find a midpoint");
return ((l.elem[0].p).Plus(l.elem[1].p)).ScaledBy(0.5);
return ((l[0].p).Plus(l[1].p)).ScaledBy(0.5);
}
bool SContour::IsClockwiseProjdToNormal(Vector n) const {
@ -620,10 +622,10 @@ double SContour::SignedAreaProjdToNormal(Vector n) const {
double area = 0;
for(int i = 0; i < (l.n - 1); i++) {
double u0 = (l.elem[i ].p).Dot(u);
double v0 = (l.elem[i ].p).Dot(v);
double u1 = (l.elem[i+1].p).Dot(u);
double v1 = (l.elem[i+1].p).Dot(v);
double u0 = (l[i ].p).Dot(u);
double v0 = (l[i ].p).Dot(v);
double u1 = (l[i+1].p).Dot(u);
double v1 = (l[i+1].p).Dot(v);
area += ((v0 + v1)/2)*(u1 - u0);
}
@ -639,11 +641,11 @@ bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) const {
bool inside = false;
for(int i = 0; i < (l.n - 1); i++) {
double ua = (l.elem[i ].p).Dot(u);
double va = (l.elem[i ].p).Dot(v);
double ua = (l[i ].p).Dot(u);
double va = (l[i ].p).Dot(v);
// The curve needs to be exactly closed; approximation is death.
double ub = (l.elem[(i+1)%(l.n-1)].p).Dot(u);
double vb = (l.elem[(i+1)%(l.n-1)].p).Dot(v);
double ub = (l[(i+1)%(l.n-1)].p).Dot(u);
double vb = (l[(i+1)%(l.n-1)].p).Dot(v);
if ((((va <= vp) && (vp < vb)) ||
((vb <= vp) && (vp < va))) &&
@ -664,7 +666,7 @@ void SContour::Reverse() {
void SPolygon::Clear() {
int i;
for(i = 0; i < l.n; i++) {
(l.elem[i]).l.Clear();
(l[i]).l.Clear();
}
l.Clear();
}
@ -677,13 +679,13 @@ void SPolygon::AddEmptyContour() {
void SPolygon::MakeEdgesInto(SEdgeList *el) const {
int i;
for(i = 0; i < l.n; i++) {
(l.elem[i]).MakeEdgesInto(el);
(l[i]).MakeEdgesInto(el);
}
}
Vector SPolygon::ComputeNormal() const {
if(l.n < 1) return Vector::From(0, 0, 0);
return (l.elem[0]).ComputeNormal();
return (l[0]).ComputeNormal();
}
double SPolygon::SignedArea() const {
@ -704,7 +706,7 @@ int SPolygon::WindingNumberForPoint(Vector p) const {
int winding = 0;
int i;
for(i = 0; i < l.n; i++) {
SContour *sc = &(l.elem[i]);
const SContour *sc = &(l[i]);
if(sc->ContainsPointProjdToNormal(normal, p)) {
winding++;
}
@ -719,18 +721,18 @@ void SPolygon::FixContourDirections() {
// Outside curve looks counterclockwise, projected against our normal.
int i, j;
for(i = 0; i < l.n; i++) {
SContour *sc = &(l.elem[i]);
SContour *sc = &(l[i]);
if(sc->l.n < 2) continue;
// The contours may not intersect, but they may share vertices; so
// testing a vertex for point-in-polygon may fail, but the midpoint
// of an edge is okay.
Vector pt = (((sc->l.elem[0]).p).Plus(sc->l.elem[1].p)).ScaledBy(0.5);
Vector pt = (((sc->l[0]).p).Plus(sc->l[1].p)).ScaledBy(0.5);
sc->timesEnclosed = 0;
bool outer = true;
for(j = 0; j < l.n; j++) {
if(i == j) continue;
SContour *sct = &(l.elem[j]);
SContour *sct = &(l[j]);
if(sct->ContainsPointProjdToNormal(normal, pt)) {
outer = !outer;
(sc->timesEnclosed)++;
@ -753,7 +755,7 @@ bool SPolygon::IsEmpty() const {
Vector SPolygon::AnyPoint() const {
ssassert(!IsEmpty(), "Need at least one point");
return l.elem[0].l.elem[0].p;
return l[0].l[0].p;
}
bool SPolygon::SelfIntersecting(Vector *intersectsAt) const {
@ -799,9 +801,9 @@ void SPolygon::OffsetInto(SPolygon *dest, double r) const {
int i;
dest->Clear();
for(i = 0; i < l.n; i++) {
SContour *sc = &(l.elem[i]);
const SContour *sc = &(l[i]);
dest->AddEmptyContour();
sc->OffsetInto(&(dest->l.elem[dest->l.n-1]), r);
sc->OffsetInto(&(dest->l[dest->l.n-1]), r);
}
}
//-----------------------------------------------------------------------------
@ -856,9 +858,9 @@ void SContour::OffsetInto(SContour *dest, double r) const {
Vector dp, dn;
double thetan, thetap;
a = l.elem[WRAP(i-1, (l.n-1))].p;
b = l.elem[WRAP(i, (l.n-1))].p;
c = l.elem[WRAP(i+1, (l.n-1))].p;
a = l[WRAP(i-1, (l.n-1))].p;
b = l[WRAP(i, (l.n-1))].p;
c = l[WRAP(i+1, (l.n-1))].p;
dp = a.Minus(b);
thetap = atan2(dp.y, dp.x);

View File

@ -244,7 +244,7 @@ MeshRenderer::Handle MeshRenderer::Add(const SMesh &m, bool dynamic) {
MeshVertex *vertices = new MeshVertex[m.l.n * 3];
for(int i = 0; i < m.l.n; i++) {
const STriangle &t = m.l.elem[i];
const STriangle &t = m.l[i];
vertices[i * 3 + 0].pos = Vector3f::From(t.a);
vertices[i * 3 + 1].pos = Vector3f::From(t.b);
vertices[i * 3 + 2].pos = Vector3f::From(t.c);
@ -485,8 +485,8 @@ EdgeRenderer::Handle EdgeRenderer::Add(const SEdgeList &edges, bool dynamic) {
uint32_t curVertex = 0;
uint32_t curIndex = 0;
for(int i = 0; i < edges.l.n; i++) {
const SEdge &curr = edges.l.elem[i];
const SEdge &next = edges.l.elem[(i + 1) % edges.l.n];
const SEdge &curr = edges.l[i];
const SEdge &next = edges.l[(i + 1) % edges.l.n];
// 3d positions
Vector3f a = Vector3f::From(curr.a);
@ -674,8 +674,8 @@ OutlineRenderer::Handle OutlineRenderer::Add(const SOutlineList &outlines, bool
uint32_t curIndex = 0;
for(int i = 0; i < outlines.l.n; i++) {
const SOutline &curr = outlines.l.elem[i];
const SOutline &next = outlines.l.elem[(i + 1) % outlines.l.n];
const SOutline &curr = outlines.l[i];
const SOutline &next = outlines.l[(i + 1) % outlines.l.n];
// 3d positions
Vector3f a = Vector3f::From(curr.a);

View File

@ -243,7 +243,7 @@ void SurfaceRenderer::ConvertBeziersToEdges() {
List<Vector> lv = {};
b.MakePwlInto(&lv, chordTolerance);
for(int i = 1; i < lv.n; i++) {
el.AddEdge(lv.elem[i-1], lv.elem[i]);
el.AddEdge(lv[i-1], lv[i]);
}
lv.Clear();
}

View File

@ -777,7 +777,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
double vol = 0;
int i;
for(i = 0; i < m->l.n; i++) {
STriangle tr = m->l.elem[i];
STriangle tr = m->l[i];
// Translate to place vertex A at (x, y, 0)
Vector trans = Vector::From(tr.a.x, tr.a.y, 0);
@ -907,7 +907,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
int i;
SContour *sc = &(SS.traced.path);
for(i = 0; i < sc->l.n; i++) {
Vector p = sc->l.elem[i].p;
Vector p = sc->l[i].p;
double s = SS.exportScale;
fprintf(f, "%.10f, %.10f, %.10f\r\n",
p.x/s, p.y/s, p.z/s);

View File

@ -293,16 +293,16 @@ void SSurface::FindChainAvoiding(SEdgeList *src, SEdgeList *dest,
{
ssassert(!src->l.IsEmpty(), "Need at least one edge");
// Start with an arbitrary edge.
dest->l.Add(&(src->l.elem[0]));
dest->l.Add(&(src->l[0]));
src->l.ClearTags();
src->l.elem[0].tag = 1;
src->l[0].tag = 1;
bool added;
do {
added = false;
// The start and finish of the current edge chain
Vector s = dest->l.elem[0].a,
f = dest->l.elem[dest->l.n - 1].b;
Vector s = dest->l[0].a,
f = dest->l[dest->l.n - 1].b;
// 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.
@ -445,8 +445,8 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
int i;
for(i = 1; i < sc->pts.n; i++) {
Vector a = sc->pts.elem[i-1].p,
b = sc->pts.elem[i].p;
Vector a = sc->pts[i-1].p,
b = sc->pts[i].p;
Point2d auv, buv;
ss->ClosestPointTo(a, &(auv.x), &(auv.y));
@ -512,7 +512,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
// Arbitrarily choose an edge within the chain to classify; they
// should all be the same, though.
se = &(chain.l.elem[chain.l.n/2]);
se = &(chain.l[chain.l.n/2]);
Point2d auv = (se->a).ProjectXy(),
buv = (se->b).ProjectXy();
@ -545,7 +545,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
FindChainAvoiding(&inter, &chain, &choosing);
// Any edge in the chain, same as above.
se = &(chain.l.elem[chain.l.n/2]);
se = &(chain.l[chain.l.n/2]);
Point2d auv = (se->a).ProjectXy(),
buv = (se->b).ProjectXy();

View File

@ -239,12 +239,12 @@ void SBezierList::CullIdenticalBeziers(bool both) {
l.ClearTags();
for(i = 0; i < l.n; i++) {
SBezier *bi = &(l.elem[i]), bir;
SBezier *bi = &(l[i]), bir;
bir = *bi;
bir.Reverse();
for(j = i + 1; j < l.n; j++) {
SBezier *bj = &(l.elem[j]);
SBezier *bj = &(l[j]);
if(bj->Equals(bi) ||
bj->Equals(&bir))
{
@ -312,7 +312,7 @@ bool SBezierList::GetPlaneContainingBeziers(Vector *p, Vector *u, Vector *v,
// Get any point on any Bezier; or an arbitrary point if list is empty.
if(!l.IsEmpty()) {
pt = l.elem[0].Start();
pt = l[0].Start();
} else {
pt = Vector::From(0, 0, 0);
}
@ -393,7 +393,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
if(sbl->l.n < 1) return loop;
sbl->l.ClearTags();
SBezier *first = &(sbl->l.elem[0]);
SBezier *first = &(sbl->l[0]);
first->tag = 1;
loop.l.Add(first);
Vector start = first->Start();
@ -406,7 +406,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
int i;
bool foundNext = false;
for(i = 0; i < sbl->l.n; i++) {
SBezier *test = &(sbl->l.elem[i]);
SBezier *test = &(sbl->l[i]);
if((test->Finish()).Equals(hanging) && test->auxA == auxA) {
test->Reverse();
@ -470,15 +470,15 @@ void SBezierLoop::MakePwlInto(SContour *sc, double chordTol) const {
}
}
// Ensure that it's exactly closed, not just within a numerical tolerance.
if((sc->l.elem[sc->l.n - 1].p).Equals(sc->l.elem[0].p)) {
sc->l.elem[sc->l.n - 1] = sc->l.elem[0];
if((sc->l[sc->l.n - 1].p).Equals(sc->l[0].p)) {
sc->l[sc->l.n - 1] = sc->l[0];
}
}
bool SBezierLoop::IsClosed() const {
if(l.n < 1) return false;
Vector s = l.elem[0].Start(),
f = l.elem[l.n-1].Finish();
Vector s = l[0].Start(),
f = l[l.n-1].Finish();
return s.Equals(f);
}
@ -512,7 +512,7 @@ SBezierLoopSet SBezierLoopSet::From(SBezierList *sbl, SPolygon *poly,
} else {
ret.l.Add(&loop);
poly->AddEmptyContour();
loop.MakePwlInto(&(poly->l.elem[poly->l.n-1]), chordTol);
loop.MakePwlInto(&(poly->l[poly->l.n-1]), chordTol);
}
}
@ -553,14 +553,14 @@ double SBezierLoopSet::SignedArea() {
void SBezierLoopSet::MakePwlInto(SPolygon *sp) const {
for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) {
sp->AddEmptyContour();
sbl->MakePwlInto(&(sp->l.elem[sp->l.n - 1]));
sbl->MakePwlInto(&(sp->l[sp->l.n - 1]));
}
}
void SBezierLoopSet::Clear() {
int i;
for(i = 0; i < l.n; i++) {
(l.elem[i]).Clear();
(l[i]).Clear();
}
l.Clear();
}
@ -618,7 +618,7 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
for(pt = sc->l.First(); pt; pt = sc->l.NextAfter(pt)) {
double u, v;
srfuv->ClosestPointTo(pt->p, &u, &v);
spuv.l.elem[spuv.l.n - 1].AddPoint(Vector::From(u, v, 0));
spuv.l[spuv.l.n - 1].AddPoint(Vector::From(u, v, 0));
}
}
spuv.normal = Vector::From(0, 0, 1); // must be, since it's in xy plane now
@ -630,8 +630,8 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
// works for curved surfaces too (important for STEP export).
spuv.FixContourDirections();
for(i = 0; i < spuv.l.n; i++) {
SContour *contour = &(spuv.l.elem[i]);
SBezierLoop *bl = &(sbls.l.elem[i]);
SContour *contour = &(spuv.l[i]);
SBezierLoop *bl = &(sbls.l[i]);
if(contour->tag) {
// This contour got reversed in the polygon to make the directions
// consistent, so the same must be necessary for the Bezier loop.
@ -648,7 +648,7 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
while(loopsRemaining) {
loopsRemaining = false;
for(i = 0; i < sbls.l.n; i++) {
SBezierLoop *loop = &(sbls.l.elem[i]);
SBezierLoop *loop = &(sbls.l[i]);
if(loop->tag != OUTER_LOOP) continue;
// Check if this contour contains any outer loops; if it does, then
@ -656,12 +656,12 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
// will steal their holes, since their holes also lie inside this
// contour.
for(j = 0; j < sbls.l.n; j++) {
SBezierLoop *outer = &(sbls.l.elem[j]);
SBezierLoop *outer = &(sbls.l[j]);
if(i == j) continue;
if(outer->tag != OUTER_LOOP) continue;
Vector p = spuv.l.elem[j].AnyEdgeMidpoint();
if(spuv.l.elem[i].ContainsPointProjdToNormal(spuv.normal, p)) {
Vector p = spuv.l[j].AnyEdgeMidpoint();
if(spuv.l[i].ContainsPointProjdToNormal(spuv.normal, p)) {
break;
}
}
@ -675,16 +675,16 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
loop->tag = USED_LOOP;
outerAndInners.l.Add(loop);
int auxA = 0;
if(loop->l.n > 0) auxA = loop->l.elem[0].auxA;
if(loop->l.n > 0) auxA = loop->l[0].auxA;
for(j = 0; j < sbls.l.n; j++) {
SBezierLoop *inner = &(sbls.l.elem[j]);
SBezierLoop *inner = &(sbls.l[j]);
if(inner->tag != INNER_LOOP) continue;
if(inner->l.n < 1) continue;
if(inner->l.elem[0].auxA != auxA) continue;
if(inner->l[0].auxA != auxA) continue;
Vector p = spuv.l.elem[j].AnyEdgeMidpoint();
if(spuv.l.elem[i].ContainsPointProjdToNormal(spuv.normal, p)) {
Vector p = spuv.l[j].AnyEdgeMidpoint();
if(spuv.l[i].ContainsPointProjdToNormal(spuv.normal, p)) {
outerAndInners.l.Add(inner);
inner->tag = USED_LOOP;
}
@ -702,7 +702,7 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
// to screw up on that stuff. So just add them onto the open curve list.
// Very ugly, but better than losing curves.
for(i = 0; i < sbls.l.n; i++) {
SBezierLoop *loop = &(sbls.l.elem[i]);
SBezierLoop *loop = &(sbls.l[i]);
if(loop->tag == USED_LOOP) continue;
if(openContours) {
@ -804,11 +804,11 @@ void SCurve::RemoveShortSegments(SSurface *srfA, SSurface *srfB) {
if(pts.n <= 3) return;
pts.ClearTags();
Vector prev = pts.elem[0].p;
Vector prev = pts[0].p;
int i, a;
for(i = 1; i < pts.n - 1; i++) {
SCurvePt *sct = &(pts.elem[i]),
*scn = &(pts.elem[i+1]);
SCurvePt *sct = &(pts[i]),
*scn = &(pts[i+1]);
if(sct->vertex) {
prev = sct->p;
continue;
@ -849,12 +849,12 @@ STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc, bool backwards) {
SCurve *sc = shell->curve.FindById(hsc);
if(backwards) {
stb.finish = sc->pts.elem[0].p;
stb.start = sc->pts.elem[sc->pts.n - 1].p;
stb.finish = sc->pts[0].p;
stb.start = sc->pts[sc->pts.n - 1].p;
stb.backwards = true;
} else {
stb.start = sc->pts.elem[0].p;
stb.finish = sc->pts.elem[sc->pts.n - 1].p;
stb.start = sc->pts[0].p;
stb.finish = sc->pts[sc->pts.n - 1].p;
stb.backwards = false;
}

View File

@ -13,7 +13,7 @@ void SShell::MergeCoincidentSurfaces() {
SSurface *si, *sj;
for(i = 0; i < surface.n; i++) {
si = &(surface.elem[i]);
si = &(surface[i]);
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.
@ -31,7 +31,7 @@ void SShell::MergeCoincidentSurfaces() {
mergedThisTime = false;
for(j = i + 1; j < surface.n; j++) {
sj = &(surface.elem[j]);
sj = &(surface[j]);
if(sj->tag) continue;
if(!sj->CoincidentWith(si, /*sameNormal=*/true)) continue;
if(!sj->color.Equals(si->color)) continue;

View File

@ -231,7 +231,7 @@ void SBezier::MakePwlInto(SEdgeList *sel, double chordTol) const {
MakePwlInto(&lv, chordTol);
int i;
for(i = 1; i < lv.n; i++) {
sel->AddEdge(lv.elem[i-1], lv.elem[i]);
sel->AddEdge(lv[i-1], lv[i]);
}
lv.Clear();
}
@ -242,7 +242,7 @@ void SBezier::MakePwlInto(List<SCurvePt> *l, double chordTol) const {
for(i = 0; i < lv.n; i++) {
SCurvePt scpt;
scpt.tag = 0;
scpt.p = lv.elem[i];
scpt.p = lv[i];
scpt.vertex = (i == 0) || (i == (lv.n - 1));
l->Add(&scpt);
}
@ -253,7 +253,7 @@ void SBezier::MakePwlInto(SContour *sc, double chordTol) const {
MakePwlInto(&lv, chordTol);
int i;
for(i = 0; i < lv.n; i++) {
sc->AddPoint(lv.elem[i]);
sc->AddPoint(lv[i]);
}
lv.Clear();
}

View File

@ -342,15 +342,15 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
int i, j;
for(i = 0; i < inters.n; i++) {
for(j = i + 1; j < inters.n; j++) {
if(inters.elem[i].p.Equals(inters.elem[j].p)) {
inters.elem[j].tag = 1;
if(inters[i].p.Equals(inters[j].p)) {
inters[j].tag = 1;
}
}
}
inters.RemoveTagged();
for(i = 0; i < inters.n; i++) {
Point2d puv = inters.elem[i].p;
Point2d puv = inters[i].p;
// Make sure the point lies within the finite line segment
Vector pxyz = PointAt(puv.x, puv.y);

View File

@ -235,7 +235,7 @@ void SSurface::MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags,
increment = 1;
}
for(i = first; i != (last + increment); i += increment) {
Vector tpt, *pt = &(sc->pts.elem[i].p);
Vector tpt, *pt = &(sc->pts[i].p);
if(flags == MakeAs::UV) {
ClosestPointTo(*pt, &u, &v);
@ -343,11 +343,11 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
int sp, fp;
for(sp = 0; sp < sc->pts.n; sp++) {
if(s.Equals(sc->pts.elem[sp].p)) break;
if(s.Equals(sc->pts[sp].p)) break;
}
if(sp >= sc->pts.n) return;
for(fp = sp; fp < sc->pts.n; fp++) {
if(f.Equals(sc->pts.elem[fp].p)) break;
if(f.Equals(sc->pts[fp].p)) break;
}
if(fp >= sc->pts.n) return;
// So now the curve we want goes from elem[sp] to elem[fp]
@ -360,8 +360,8 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
for(;;) {
// So construct a cubic Bezier with the correct endpoints
// and tangents for the current span.
Vector st = sc->pts.elem[sp].p,
ft = sc->pts.elem[fpt].p,
Vector st = sc->pts[sp].p,
ft = sc->pts[fpt].p,
sf = ft.Minus(st);
double m = sf.Magnitude() / 3;
@ -378,7 +378,7 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
int i;
bool tooFar = false;
for(i = sp + 1; i <= (fpt - 1); i++) {
Vector p = sc->pts.elem[i].p;
Vector p = sc->pts[i].p;
double t;
sb.ClosestPointTo(p, &t, /*mustConverge=*/false);
Vector pp = sb.PointAt(t);
@ -435,7 +435,7 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
STriMeta meta = { face, color };
for(i = start; i < sm->l.n; i++) {
STriangle *st = &(sm->l.elem[i]);
STriangle *st = &(sm->l[i]);
st->meta = meta;
st->an = NormalAt(st->a.x, st->a.y);
st->bn = NormalAt(st->b.x, st->b.y);
@ -588,10 +588,10 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, Rgb
int i;
for(i = 0; i < trimLines.n; i++) {
TrimLine *tl = &(trimLines.elem[i]);
TrimLine *tl = &(trimLines[i]);
SSurface *ss = surface.FindById(tl->hs);
TrimLine *tlp = &(trimLines.elem[WRAP(i-1, trimLines.n)]);
TrimLine *tlp = &(trimLines[WRAP(i-1, trimLines.n)]);
STrimBy stb;
stb = STrimBy::EntireCurve(this, tl->hc, /*backwards=*/true);
@ -726,9 +726,9 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector
}
// Still the same loop. Need to create trim curves
for(i = 0; i < sbl->l.n; i++) {
Revolved revs = hsl.elem[i], revsp = hsl.elem[WRAP(i - 1, sbl->l.n)];
Revolved revs = hsl[i], revsp = hsl[WRAP(i - 1, sbl->l.n)];
sb = &(sbl->l.elem[i]);
sb = &(sbl->l[i]);
// we generate one more curve than we did surfaces
for(j = 0; j <= sections; j++) {
@ -858,10 +858,10 @@ void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis,
}
for(i = 0; i < sbl->l.n; i++) {
Revolved revs = hsl.elem[i],
revsp = hsl.elem[WRAP(i-1, sbl->l.n)];
Revolved revs = hsl[i],
revsp = hsl[WRAP(i-1, sbl->l.n)];
sb = &(sbl->l.elem[i]);
sb = &(sbl->l[i]);
for(j = 0; j < 4; j++) {
SCurve sc;
@ -925,7 +925,7 @@ void SShell::MakeFirstOrderRevolvedSurfaces(Vector pt, Vector axis, int i0) {
int i;
for(i = i0; i < surface.n; i++) {
SSurface *srf = &(surface.elem[i]);
SSurface *srf = &(surface[i]);
// Revolution of a line; this is potentially a plane, which we can
// rewrite to have degree (1, 1).

View File

@ -277,7 +277,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
int i;
for(i = 0; i < lv.n - 1; i++) {
Vector pa = lv.elem[i], pb = lv.elem[i+1];
Vector pa = lv[i], pb = lv[i+1];
pa = pa.Minus(axis.ScaledBy(pa.Dot(axis)));
pb = pb.Minus(axis.ScaledBy(pb.Dot(axis)));
pa = pa.Plus(axisc);
@ -369,10 +369,10 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
sc.isExact = false;
sc.source = SCurve::Source::INTERSECTION;
Vector start = spl.l.elem[0].p,
startv = spl.l.elem[0].auxv;
Vector start = spl.l[0].p,
startv = spl.l[0].auxv;
spl.l.ClearTags();
spl.l.elem[0].tag = 1;
spl.l[0].tag = 1;
spl.l.RemoveTagged();
// Our chord tolerance is whatever the user specified

View File

@ -114,7 +114,7 @@ bool SContour::BridgeToContour(SContour *sc,
// point.
int sco = 0;
for(i = 0; i < (sc->l.n - 1); i++) {
if((sc->l.elem[i].p).EqualsExactly(sc->xminPt)) {
if((sc->l[i].p).EqualsExactly(sc->xminPt)) {
sco = i;
}
}
@ -124,7 +124,7 @@ bool SContour::BridgeToContour(SContour *sc,
int thiso = 0;
double dmin = 1e10;
for(i = 0; i < l.n; i++) {
Vector p = l.elem[i].p;
Vector p = l[i].p;
double d = (p.Minus(sc->xminPt)).MagSquared();
if(d < dmin) {
dmin = d;
@ -140,7 +140,7 @@ bool SContour::BridgeToContour(SContour *sc,
// merge them there, without a bridge.
for(i = 0; i < l.n; i++) {
thisp = WRAP(i+thiso, l.n);
a = l.elem[thisp].p;
a = l[thisp].p;
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
if(f->Equals(a)) break;
@ -149,7 +149,7 @@ bool SContour::BridgeToContour(SContour *sc,
for(j = 0; j < (sc->l.n - 1); j++) {
scp = WRAP(j+sco, (sc->l.n - 1));
b = sc->l.elem[scp].p;
b = sc->l[scp].p;
if(a.Equals(b)) {
goto haveEdge;
@ -160,7 +160,7 @@ bool SContour::BridgeToContour(SContour *sc,
// If that fails, look for a bridge that does not intersect any edges.
for(i = 0; i < l.n; i++) {
thisp = WRAP(i+thiso, l.n);
a = l.elem[thisp].p;
a = l[thisp].p;
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
if(f->Equals(a)) break;
@ -169,7 +169,7 @@ bool SContour::BridgeToContour(SContour *sc,
for(j = 0; j < (sc->l.n - 1); j++) {
scp = WRAP(j+sco, (sc->l.n - 1));
b = sc->l.elem[scp].p;
b = sc->l[scp].p;
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
if(f->Equals(b)) break;
@ -190,15 +190,15 @@ bool SContour::BridgeToContour(SContour *sc,
haveEdge:
SContour merged = {};
for(i = 0; i < l.n; i++) {
merged.AddPoint(l.elem[i].p);
merged.AddPoint(l[i].p);
if(i == thisp) {
// less than or equal; need to duplicate the join point
for(j = 0; j <= (sc->l.n - 1); j++) {
int jp = WRAP(j + scp, (sc->l.n - 1));
merged.AddPoint((sc->l.elem[jp]).p);
merged.AddPoint((sc->l[jp]).p);
}
// and likewise duplicate join point for the outer curve
merged.AddPoint(l.elem[i].p);
merged.AddPoint(l[i].p);
}
}
@ -218,9 +218,9 @@ bool SContour::IsEar(int bp, double scaledEps) const {
cp = WRAP(bp+1, l.n);
STriangle tr = {};
tr.a = l.elem[ap].p;
tr.b = l.elem[bp].p;
tr.c = l.elem[cp].p;
tr.a = l[ap].p;
tr.b = l[bp].p;
tr.c = l[cp].p;
if((tr.a).Equals(tr.c)) {
// This is two coincident and anti-parallel edges. Zero-area, so
@ -244,7 +244,7 @@ bool SContour::IsEar(int bp, double scaledEps) const {
for(i = 0; i < l.n; i++) {
if(i == ap || i == bp || i == cp) continue;
Vector p = l.elem[i].p;
Vector p = l[i].p;
if(p.OutsideAndNotOn(maxv, minv)) continue;
// A point on the edge of the triangle is considered to be inside,
@ -266,9 +266,9 @@ void SContour::ClipEarInto(SMesh *m, int bp, double scaledEps) {
cp = WRAP(bp+1, l.n);
STriangle tr = {};
tr.a = l.elem[ap].p;
tr.b = l.elem[bp].p;
tr.c = l.elem[cp].p;
tr.a = l[ap].p;
tr.b = l[bp].p;
tr.c = l[cp].p;
if(tr.Normal().MagSquared() < scaledEps*scaledEps) {
// A vertex with more than two edges will cause us to generate
// zero-area triangles, which must be culled.
@ -278,11 +278,11 @@ void SContour::ClipEarInto(SMesh *m, int bp, double scaledEps) {
// By deleting the point at bp, we may change the ear-ness of the points
// on either side.
l.elem[ap].ear = EarType::UNKNOWN;
l.elem[cp].ear = EarType::UNKNOWN;
l[ap].ear = EarType::UNKNOWN;
l[cp].ear = EarType::UNKNOWN;
l.ClearTags();
l.elem[bp].tag = 1;
l[bp].tag = 1;
l.RemoveTagged();
}
@ -299,23 +299,23 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
// Clean the original contour by removing any zero-length edges.
l.ClearTags();
for(i = 1; i < l.n; i++) {
if((l.elem[i].p).Equals(l.elem[i-1].p)) {
l.elem[i].tag = 1;
if((l[i].p).Equals(l[i-1].p)) {
l[i].tag = 1;
}
}
l.RemoveTagged();
// Now calculate the ear-ness of each vertex
for(i = 0; i < l.n; i++) {
(l.elem[i]).ear = IsEar(i, scaledEps) ? EarType::EAR : EarType::NOT_EAR;
(l[i]).ear = IsEar(i, scaledEps) ? EarType::EAR : EarType::NOT_EAR;
}
bool toggle = false;
while(l.n > 3) {
// Some points may have changed ear-ness, so recalculate
for(i = 0; i < l.n; i++) {
if(l.elem[i].ear == EarType::UNKNOWN) {
(l.elem[i]).ear = IsEar(i, scaledEps) ?
if(l[i].ear == EarType::UNKNOWN) {
(l[i]).ear = IsEar(i, scaledEps) ?
EarType::EAR : EarType::NOT_EAR;
}
}
@ -328,7 +328,7 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
int offset = toggle ? -1 : 0;
for(i = 0; i < l.n; i++) {
int ear = WRAP(i+offset, l.n);
if(l.elem[ear].ear == EarType::EAR) {
if(l[ear].ear == EarType::EAR) {
if(srf->degm == 1 && srf->degn == 1) {
// This is a plane; any ear is a good ear.
bestEar = ear;
@ -337,8 +337,8 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
// If we are triangulating a curved surface, then try to
// clip ears that have a small chord tolerance from the
// surface.
Vector prev = l.elem[WRAP((i+offset-1), l.n)].p,
next = l.elem[WRAP((i+offset+1), l.n)].p;
Vector prev = l[WRAP((i+offset-1), l.n)].p,
next = l[WRAP((i+offset+1), l.n)].p;
double tol = srf->ChordToleranceForEdge(prev, next);
if(tol < bestChordTol - scaledEps) {
bestEar = ear;
@ -444,8 +444,8 @@ void SPolygon::UvGridTriangulateInto(SMesh *mesh, SSurface *srf) {
int i, j;
for(i = 0; i < (li.n - 1); i++) {
for(j = 0; j < (lj.n - 1); j++) {
double us = li.elem[i], uf = li.elem[i+1],
vs = lj.elem[j], vf = lj.elem[j+1];
double us = li[i], uf = li[i+1],
vs = lj[j], vf = lj[j+1];
Vector a = Vector::From(us, vs, 0),
b = Vector::From(us, vf, 0),

View File

@ -404,11 +404,11 @@ SolveResult System::Solve(Group *g, int *rank, int *dof, List<hConstraint> *bad,
/*
dbp("%d equations", eq.n);
for(i = 0; i < eq.n; i++) {
dbp(" %.3f = %s = 0", eq.elem[i].e->Eval(), eq.elem[i].e->Print());
dbp(" %.3f = %s = 0", eq[i].e->Eval(), eq[i].e->Print());
}
dbp("%d parameters", param.n);
for(i = 0; i < param.n; i++) {
dbp(" param %08x at %.3f", param.elem[i].h.v, param.elem[i].val);
dbp(" param %08x at %.3f", param[i].h.v, param[i].val);
} */
// All params and equations are assigned to group zero.

View File

@ -534,7 +534,7 @@ void TextWindow::ShowGroupSolveInfo() {
}
for(int i = 0; i < g->solved.remove.n; i++) {
hConstraint hc = g->solved.remove.elem[i];
hConstraint hc = g->solved.remove[i];
Constraint *c = SK.constraint.FindByIdNoOops(hc);
if(!c) continue;

View File

@ -72,14 +72,14 @@ void TtfFontList::LoadAll() {
}
// Sort fonts according to their actual name, not filename.
std::sort(&l.elem[0], &l.elem[l.n],
std::sort(&l[0], &l[l.n],
[](const TtfFont &a, const TtfFont &b) { return a.name < b.name; });
// Filter out fonts with the same family and style name. This is not
// strictly necessarily the exact same font, but it will almost always be.
TtfFont *it = std::unique(&l.elem[0], &l.elem[l.n],
TtfFont *it = std::unique(&l[0], &l[l.n],
[](const TtfFont &a, const TtfFont &b) { return a.name == b.name; });
l.RemoveLast(&l.elem[l.n] - it);
l.RemoveLast(&l[l.n] - it);
// TODO: identify fonts by their name and not filename, which may change
// between OSes.