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
parent
482f0e8de9
commit
0bfbbe2bf3
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)++;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
23
src/dsc.h
23
src/dsc.h
|
@ -202,12 +202,13 @@ public:
|
|||
};
|
||||
|
||||
// A simple list
|
||||
template <class T>
|
||||
template<class T>
|
||||
class List {
|
||||
T *elem = nullptr;
|
||||
int elemsAllocated = 0;
|
||||
|
||||
public:
|
||||
T *elem = nullptr;
|
||||
int n = 0;
|
||||
int elemsAllocated = 0;
|
||||
|
||||
bool IsEmpty() const { return n == 0; }
|
||||
|
||||
|
@ -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]; }
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
28
src/mesh.cpp
28
src/mesh.cpp
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue