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) {
|
while(n > 1) {
|
||||||
int k = rand() % n;
|
int k = rand() % n;
|
||||||
n--;
|
n--;
|
||||||
swap(mc.l.elem[k], mc.l.elem[n]);
|
swap(mc.l[k], mc.l[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
SBsp3 *bsp3 = NULL;
|
SBsp3 *bsp3 = NULL;
|
||||||
|
|
|
@ -172,7 +172,7 @@ void ConstraintBase::ModifyToSatisfy() {
|
||||||
|
|
||||||
// These equations are written in the form f(...) - d = 0, where
|
// These equations are written in the form f(...) - d = 0, where
|
||||||
// d is the value of the valA.
|
// d is the value of the valA.
|
||||||
valA += (l.elem[0].e)->Eval();
|
valA += (l[0].e)->Eval();
|
||||||
|
|
||||||
l.Clear();
|
l.Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ void TextWindow::ScreenSetTtfFont(int link, uint32_t v) {
|
||||||
if(!r) return;
|
if(!r) return;
|
||||||
|
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
r->font = SS.fonts.l.elem[i].FontFileBaseName();
|
r->font = SS.fonts.l[i].FontFileBaseName();
|
||||||
SS.MarkGroupDirty(r->group);
|
SS.MarkGroupDirty(r->group);
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ void TextWindow::DescribeSelection() {
|
||||||
SS.fonts.LoadAll();
|
SS.fonts.LoadAll();
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SS.fonts.l.n; 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()) {
|
if(e->font == tf->FontFileBaseName()) {
|
||||||
Printf(false, "%Bp %s",
|
Printf(false, "%Bp %s",
|
||||||
(i & 1) ? 'd' : 'a',
|
(i & 1) ? 'd' : 'a',
|
||||||
|
|
|
@ -233,7 +233,7 @@ void GraphicsWindow::GroupSelection() {
|
||||||
gs = {};
|
gs = {};
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < selection.n; i++) {
|
for(i = 0; i < selection.n; i++) {
|
||||||
Selection *s = &(selection.elem[i]);
|
Selection *s = &(selection[i]);
|
||||||
if(s->entity.v) {
|
if(s->entity.v) {
|
||||||
(gs.n)++;
|
(gs.n)++;
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,12 @@ void Entity::GenerateEdges(SEdgeList *el) {
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < sbl->l.n; i++) {
|
for(i = 0; i < sbl->l.n; i++) {
|
||||||
SBezier *sb = &(sbl->l.elem[i]);
|
SBezier *sb = &(sbl->l[i]);
|
||||||
|
|
||||||
List<Vector> lv = {};
|
List<Vector> lv = {};
|
||||||
sb->MakePwlInto(&lv);
|
sb->MakePwlInto(&lv);
|
||||||
for(j = 1; j < lv.n; j++) {
|
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();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) {
|
||||||
Vector proj = SK.GetEntity(point[0])->PointGetNum();
|
Vector proj = SK.GetEntity(point[0])->PointGetNum();
|
||||||
screenBBox = BBox::From(proj, proj);
|
screenBBox = BBox::From(proj, proj);
|
||||||
} else if(!sbl->l.IsEmpty()) {
|
} 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);
|
screenBBox = BBox::From(first, first);
|
||||||
for(auto &sb : sbl->l) {
|
for(auto &sb : sbl->l) {
|
||||||
for(int i = 0; i < sb.deg; ++i) { screenBBox.Include(SS.GW.ProjectPoint3(sb.ctrl[i])); }
|
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.
|
// Record our style for all of the Beziers that we just created.
|
||||||
for(; i < sbl->l.n; i++) {
|
for(; i < sbl->l.n; i++) {
|
||||||
sbl->l.elem[i].auxA = style.v;
|
sbl->l[i].auxA = style.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
src/dsc.h
21
src/dsc.h
|
@ -204,11 +204,12 @@ public:
|
||||||
// A simple list
|
// A simple list
|
||||||
template<class T>
|
template<class T>
|
||||||
class List {
|
class List {
|
||||||
public:
|
|
||||||
T *elem = nullptr;
|
T *elem = nullptr;
|
||||||
int n = 0;
|
|
||||||
int elemsAllocated = 0;
|
int elemsAllocated = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
bool IsEmpty() const { return n == 0; }
|
bool IsEmpty() const { return n == 0; }
|
||||||
|
|
||||||
void ReserveMore(int howMuch) {
|
void ReserveMore(int howMuch) {
|
||||||
|
@ -260,6 +261,11 @@ public:
|
||||||
return prev + 1;
|
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 *begin() { return IsEmpty() ? nullptr : &elem[0]; }
|
||||||
T *end() { return IsEmpty() ? nullptr : &elem[n]; }
|
T *end() { return IsEmpty() ? nullptr : &elem[n]; }
|
||||||
const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; }
|
const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; }
|
||||||
|
@ -331,10 +337,10 @@ struct CompareId {
|
||||||
// id.
|
// id.
|
||||||
template <class T, class H>
|
template <class T, class H>
|
||||||
class IdList {
|
class IdList {
|
||||||
|
T *elem = nullptr;
|
||||||
|
int elemsAllocated = 0;
|
||||||
public:
|
public:
|
||||||
T *elem;
|
int n = 0;
|
||||||
int n;
|
|
||||||
int elemsAllocated;
|
|
||||||
|
|
||||||
using Compare = CompareId<T, H>;
|
using Compare = CompareId<T, H>;
|
||||||
|
|
||||||
|
@ -450,6 +456,11 @@ public:
|
||||||
return prev + 1;
|
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 *begin() { return IsEmpty() ? nullptr : &elem[0]; }
|
||||||
T *end() { return IsEmpty() ? nullptr : &elem[n]; }
|
T *end() { return IsEmpty() ? nullptr : &elem[n]; }
|
||||||
const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; }
|
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.
|
// segments with zero-length projections.
|
||||||
sel->l.ClearTags();
|
sel->l.ClearTags();
|
||||||
for(int i = 0; i < sel->l.n; ++i) {
|
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 };
|
hStyle hsi = { (uint32_t)sei->auxA };
|
||||||
Style *si = Style::Get(hsi);
|
Style *si = Style::Get(hsi);
|
||||||
if(sei->tag != 0) continue;
|
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) {
|
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;
|
if(sej->tag != 0) continue;
|
||||||
|
|
||||||
Vector *pAj = &sej->a;
|
Vector *pAj = &sej->a;
|
||||||
|
@ -761,7 +761,7 @@ void VectorFileWriter::BezierAsPwl(SBezier *sb) {
|
||||||
sb->MakePwlInto(&lv, SS.ExportChordTolMm());
|
sb->MakePwlInto(&lv, SS.ExportChordTolMm());
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < lv.n; 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);
|
Bezier(&sb);
|
||||||
}
|
}
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
|
@ -875,7 +875,7 @@ void SolveSpaceUI::ExportMeshAsStlTo(FILE *f, SMesh *sm) {
|
||||||
double s = SS.exportScale;
|
double s = SS.exportScale;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < sm->l.n; 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);
|
Vector n = tr->Normal().WithMagnitude(1);
|
||||||
float w;
|
float w;
|
||||||
w = (float)n.x; fwrite(&w, 4, 1, f);
|
w = (float)n.x; fwrite(&w, 4, 1, f);
|
||||||
|
@ -981,7 +981,7 @@ void SolveSpaceUI::ExportMeshAsObjTo(FILE *fObj, FILE *fMtl, SMesh *sm) {
|
||||||
|
|
||||||
RgbaColor currentColor = {};
|
RgbaColor currentColor = {};
|
||||||
for(int i = 0; i < sm->l.n; i++) {
|
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)) {
|
if(!currentColor.Equals(t.meta.color)) {
|
||||||
currentColor = t.meta.color;
|
currentColor = t.meta.color;
|
||||||
fprintf(fObj, "usemtl %s\n", colors[currentColor].c_str());
|
fprintf(fObj, "usemtl %s\n", colors[currentColor].c_str());
|
||||||
|
|
|
@ -121,7 +121,7 @@ int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) {
|
||||||
|
|
||||||
List<int> listOfTrims = {};
|
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
|
// Generate "exactly closed" contours, with the same vertex id for the
|
||||||
// finish of a previous edge and the start of the next one. So we need
|
// finish of a previous edge and the start of the next one. So we need
|
||||||
|
|
|
@ -370,7 +370,7 @@ public:
|
||||||
DRW_Polyline polyline;
|
DRW_Polyline polyline;
|
||||||
assignEntityDefaults(&polyline, hs);
|
assignEntityDefaults(&polyline, hs);
|
||||||
for(int i = 0; i < lv.n; i++) {
|
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);
|
DRW_Vertex *vertex = new DRW_Vertex(v->x, v->y, v->z, 0.0);
|
||||||
polyline.vertlist.push_back(vertex);
|
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
|
// A group will have either a mesh or a shell, but not both; but the code
|
||||||
// to print either of those just does nothing if the mesh/shell is empty.
|
// to print either of those just does nothing if the mesh/shell is empty.
|
||||||
|
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[SK.groupOrder.n - 1]);
|
Group *g = SK.GetGroup(SK.groupOrder[SK.groupOrder.n - 1]);
|
||||||
SMesh *m = &g->runningMesh;
|
SMesh *m = &g->runningMesh;
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(m->l[i]);
|
||||||
fprintf(fh, "Triangle %08x %08x "
|
fprintf(fh, "Triangle %08x %08x "
|
||||||
"%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
"%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
||||||
tr->meta.face, tr->meta.color.ToPackedInt(),
|
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,
|
// Start from the first dirty group, and solve until the active group,
|
||||||
// since all groups after the active group are hidden.
|
// since all groups after the active group are hidden.
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
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()) {
|
if((!g->clean) || !g->IsSolvedOkay()) {
|
||||||
first = min(first, i);
|
first = min(first, i);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,7 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
||||||
|
|
||||||
case Generate::UNTIL_ACTIVE: {
|
case Generate::UNTIL_ACTIVE: {
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
for(i = 0; i < SK.groupOrder.n; i++) {
|
||||||
if(SK.groupOrder.elem[i] == SS.GW.activeGroup)
|
if(SK.groupOrder[i] == SS.GW.activeGroup)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
||||||
SK.entity.ReserveMore(oldEntityCount);
|
SK.entity.ReserveMore(oldEntityCount);
|
||||||
|
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
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
|
// The group may depend on entities or other groups, to define its
|
||||||
// workplane geometry or for its operands. Those must already exist
|
// workplane geometry or for its operands. Those must already exist
|
||||||
|
@ -423,7 +423,7 @@ void SolveSpaceUI::MarkDraggedParams() {
|
||||||
if(i == -1) {
|
if(i == -1) {
|
||||||
hp = SS.GW.pending.point;
|
hp = SS.GW.pending.point;
|
||||||
} else {
|
} else {
|
||||||
hp = SS.GW.pending.points.elem[i];
|
hp = SS.GW.pending.points[i];
|
||||||
}
|
}
|
||||||
if(!hp.v) continue;
|
if(!hp.v) continue;
|
||||||
|
|
||||||
|
@ -552,7 +552,7 @@ SolveResult SolveSpaceUI::TestRankForGroup(hGroup hg, int *rank) {
|
||||||
|
|
||||||
bool SolveSpaceUI::ActiveGroupsOkay() {
|
bool SolveSpaceUI::ActiveGroupsOkay() {
|
||||||
for(int i = 0; i < SK.groupOrder.n; i++) {
|
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())
|
if(!g->IsSolvedOkay())
|
||||||
return false;
|
return false;
|
||||||
if(g->h == SS.GW.activeGroup)
|
if(g->h == SS.GW.activeGroup)
|
||||||
|
|
|
@ -575,7 +575,7 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
Group *g = SK.GetGroup(activeGroup);
|
Group *g = SK.GetGroup(activeGroup);
|
||||||
g->GenerateDisplayItems();
|
g->GenerateDisplayItems();
|
||||||
for(int i = 0; i < g->displayMesh.l.n; i++) {
|
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) {
|
if(!includeMesh) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(const hEntity &face : faces) {
|
for(const hEntity &face : faces) {
|
||||||
|
@ -591,9 +591,9 @@ void GraphicsWindow::LoopOverPoints(const std::vector<Entity *> &entities,
|
||||||
}
|
}
|
||||||
if(!includeMesh) return;
|
if(!includeMesh) return;
|
||||||
for(int i = 0; i < g->polyLoops.l.n; i++) {
|
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++) {
|
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) {
|
if(useSelection) {
|
||||||
for(int i = 0; i < selection.n; i++) {
|
for(int i = 0; i < selection.n; i++) {
|
||||||
Selection *s = &selection.elem[i];
|
Selection *s = &selection[i];
|
||||||
if(s->entity.v != 0) {
|
if(s->entity.v != 0) {
|
||||||
Entity *e = SK.entity.FindById(s->entity);
|
Entity *e = SK.entity.FindById(s->entity);
|
||||||
if(e->IsFace()) {
|
if(e->IsFace()) {
|
||||||
|
@ -851,7 +851,7 @@ void GraphicsWindow::EnsureValidActives() {
|
||||||
if((!g) || (g->h == Group::HGROUP_REFERENCES)) {
|
if((!g) || (g->h == Group::HGROUP_REFERENCES)) {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SK.groupOrder.n; 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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -867,7 +867,7 @@ void GraphicsWindow::EnsureValidActives() {
|
||||||
// do it now so that drawing mode isn't switched to "Free in 3d".
|
// do it now so that drawing mode isn't switched to "Free in 3d".
|
||||||
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
|
SS.GenerateAll(SolveSpaceUI::Generate::ALL);
|
||||||
} else {
|
} else {
|
||||||
activeGroup = SK.groupOrder.elem[i];
|
activeGroup = SK.groupOrder[i];
|
||||||
}
|
}
|
||||||
SK.GetGroup(activeGroup)->Activate();
|
SK.GetGroup(activeGroup)->Activate();
|
||||||
change = true;
|
change = true;
|
||||||
|
|
|
@ -474,7 +474,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
hEntity pt = { 0 };
|
hEntity pt = { 0 };
|
||||||
// Not using range-for here because we're changing the size of entity in the loop.
|
// Not using range-for here because we're changing the size of entity in the loop.
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->Get(i));
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
|
|
||||||
if(e->IsPoint()) pt = e->h;
|
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.
|
// Not using range-for here because we're changing the size of entity in the loop.
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->Get(i));
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
|
|
||||||
e->CalculateNumerical(/*forExport=*/false);
|
e->CalculateNumerical(/*forExport=*/false);
|
||||||
|
@ -556,7 +556,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
int ai = 1;
|
int ai = 1;
|
||||||
|
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &((*entity)[i]);
|
||||||
if(e->group != opA)
|
if(e->group != opA)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
int ai = 1;
|
int ai = 1;
|
||||||
|
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->Get(i));
|
||||||
if(e->group.v != opA.v)
|
if(e->group.v != opA.v)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -660,7 +660,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
for(a = a0; a < n; a++) {
|
for(a = a0; a < n; a++) {
|
||||||
// Not using range-for here because we're changing the size of entity in the loop.
|
// Not using range-for here because we're changing the size of entity in the loop.
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->Get(i));
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
|
|
||||||
e->CalculateNumerical(/*forExport=*/false);
|
e->CalculateNumerical(/*forExport=*/false);
|
||||||
|
@ -696,7 +696,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
||||||
for(a = a0; a < n; a++) {
|
for(a = a0; a < n; a++) {
|
||||||
// Not using range-for here because we're changing the size of entity in the loop.
|
// Not using range-for here because we're changing the size of entity in the loop.
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->Get(i));
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
|
|
||||||
e->CalculateNumerical(/*forExport=*/false);
|
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.
|
// Not using range-for here because we're changing the size of entity in the loop.
|
||||||
for(i = 0; i < impEntity.n; i++) {
|
for(i = 0; i < impEntity.n; i++) {
|
||||||
Entity *ie = &(impEntity.elem[i]);
|
Entity *ie = &(impEntity[i]);
|
||||||
CopyEntity(entity, ie, 0, 0,
|
CopyEntity(entity, ie, 0, 0,
|
||||||
h.param(0), h.param(1), h.param(2),
|
h.param(0), h.param(1), h.param(2),
|
||||||
h.param(3), h.param(4), h.param(5), h.param(6), NO_PARAM,
|
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
|
// Not using range-for here because we're starting at a different place and using
|
||||||
// indices for meaning.
|
// indices for meaning.
|
||||||
for(i = is; i < thisShell.surface.n; i++) {
|
for(i = is; i < thisShell.surface.n; i++) {
|
||||||
SSurface *ss = &(thisShell.surface.elem[i]);
|
SSurface *ss = &(thisShell.surface[i]);
|
||||||
hEntity face = Entity::NO_ENTITY;
|
hEntity face = Entity::NO_ENTITY;
|
||||||
|
|
||||||
Vector p = ss->PointAt(0, 0),
|
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
|
// In an assembled loop, all the styles should be the same; so doesn't
|
||||||
// matter which one we grab.
|
// 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 });
|
Style *s = Style::Get({ (uint32_t)sb->auxA });
|
||||||
|
|
||||||
Canvas::Fill fill = {};
|
Canvas::Fill fill = {};
|
||||||
|
@ -744,7 +744,7 @@ void Group::DrawContourAreaLabels(Canvas *canvas) {
|
||||||
if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty())
|
if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty())
|
||||||
continue;
|
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 max = min;
|
||||||
Vector zero = Vector::From(0.0, 0.0, 0.0);
|
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);
|
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) {
|
if(ssys->failed) {
|
||||||
// Copy over any the list of problematic constraints.
|
// Copy over any the list of problematic constraints.
|
||||||
for(i = 0; i < ssys->faileds && i < bad.n; i++) {
|
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;
|
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);
|
*vmin = Vector::From( 1e12, 1e12, 1e12);
|
||||||
*vmax = Vector::From(-1e12, -1e12, -1e12);
|
*vmax = Vector::From(-1e12, -1e12, -1e12);
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
STriangle *st = &(l.elem[i]);
|
const STriangle *st = &(l[i]);
|
||||||
DoBounding(st->a, vmax, vmin);
|
DoBounding(st->a, vmax, vmin);
|
||||||
DoBounding(st->b, vmax, vmin);
|
DoBounding(st->b, vmax, vmin);
|
||||||
DoBounding(st->c, vmax, vmin);
|
DoBounding(st->c, vmax, vmin);
|
||||||
|
@ -70,7 +70,7 @@ void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) {
|
||||||
m.l.ClearTags();
|
m.l.ClearTags();
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < m.l.n; 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) ||
|
if((fabs(n.Dot(tr->a) - d) >= LENGTH_EPS) ||
|
||||||
(fabs(n.Dot(tr->b) - 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
|
// 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.
|
// 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.
|
// 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) {
|
void SMesh::Simplify(int start) {
|
||||||
int maxTriangles = (l.n - start) + 10;
|
int maxTriangles = (l.n - start) + 10;
|
||||||
|
|
||||||
STriMeta meta = l.elem[start].meta;
|
STriMeta meta = l[start].meta;
|
||||||
|
|
||||||
STriangle *tout = (STriangle *)MemAlloc(maxTriangles*sizeof(*tout));
|
STriangle *tout = (STriangle *)MemAlloc(maxTriangles*sizeof(*tout));
|
||||||
int toutc = 0;
|
int toutc = 0;
|
||||||
|
@ -121,7 +121,7 @@ void SMesh::Simplify(int start) {
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = start; i < l.n; i++) {
|
for(i = start; i < l.n; i++) {
|
||||||
STriangle *tr = &(l.elem[i]);
|
STriangle *tr = &(l[i]);
|
||||||
if(tr->MinAltitude() < LENGTH_EPS) {
|
if(tr->MinAltitude() < LENGTH_EPS) {
|
||||||
tr->tag = 1;
|
tr->tag = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -133,7 +133,7 @@ void SMesh::Simplify(int start) {
|
||||||
bool didAdd;
|
bool didAdd;
|
||||||
convc = 0;
|
convc = 0;
|
||||||
for(i = start; i < l.n; i++) {
|
for(i = start; i < l.n; i++) {
|
||||||
STriangle *tr = &(l.elem[i]);
|
STriangle *tr = &(l[i]);
|
||||||
if(tr->tag) continue;
|
if(tr->tag) continue;
|
||||||
|
|
||||||
tr->tag = 1;
|
tr->tag = 1;
|
||||||
|
@ -158,7 +158,7 @@ void SMesh::Simplify(int start) {
|
||||||
|
|
||||||
Vector c;
|
Vector c;
|
||||||
for(i = start; i < l.n; i++) {
|
for(i = start; i < l.n; i++) {
|
||||||
STriangle *tr = &(l.elem[i]);
|
STriangle *tr = &(l[i]);
|
||||||
if(tr->tag) continue;
|
if(tr->tag) continue;
|
||||||
|
|
||||||
if((tr->a).Equals(d) && (tr->b).Equals(b)) {
|
if((tr->a).Equals(d) && (tr->b).Equals(b)) {
|
||||||
|
@ -242,7 +242,7 @@ void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < srcm->l.n; i++) {
|
for(i = 0; i < srcm->l.n; i++) {
|
||||||
STriangle *st = &(srcm->l.elem[i]);
|
STriangle *st = &(srcm->l[i]);
|
||||||
int pn = l.n;
|
int pn = l.n;
|
||||||
atLeastOneDiscarded = false;
|
atLeastOneDiscarded = false;
|
||||||
SBsp3::InsertOrCreate(bsp3, st, this);
|
SBsp3::InsertOrCreate(bsp3, st, this);
|
||||||
|
@ -289,7 +289,7 @@ void SMesh::MakeFromDifferenceOf(SMesh *a, SMesh *b) {
|
||||||
void SMesh::MakeFromCopyOf(SMesh *a) {
|
void SMesh::MakeFromCopyOf(SMesh *a) {
|
||||||
ssassert(this != a, "Can't make from copy of self");
|
ssassert(this != a, "Can't make from copy of self");
|
||||||
for(int i = 0; i < a->l.n; i++) {
|
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;
|
uint32_t face = 0;
|
||||||
double faceT = VERY_NEGATIVE;
|
double faceT = VERY_NEGATIVE;
|
||||||
for(int i = 0; i < l.n; i++) {
|
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;
|
if(tr.meta.face == 0) continue;
|
||||||
|
|
||||||
double t;
|
double t;
|
||||||
|
@ -345,7 +345,7 @@ Vector SMesh::GetCenterOfMass() const {
|
||||||
Vector center = {};
|
Vector center = {};
|
||||||
double vol = 0.0;
|
double vol = 0.0;
|
||||||
for(int i = 0; i < l.n; i++) {
|
for(int i = 0; i < l.n; i++) {
|
||||||
STriangle &tr = l.elem[i];
|
const STriangle &tr = l[i];
|
||||||
double tvol = tr.SignedVolume();
|
double tvol = tr.SignedVolume();
|
||||||
center = center.Plus(tr.a.Plus(tr.b.Plus(tr.c)).ScaledBy(tvol / 4.0));
|
center = center.Plus(tr.a.Plus(tr.b.Plus(tr.c)).ScaledBy(tvol / 4.0));
|
||||||
vol += tvol;
|
vol += tvol;
|
||||||
|
@ -363,7 +363,7 @@ SKdNode *SKdNode::From(SMesh *m) {
|
||||||
STriangle *tra = (STriangle *)AllocTemporary((m->l.n) * sizeof(*tra));
|
STriangle *tra = (STriangle *)AllocTemporary((m->l.n) * sizeof(*tra));
|
||||||
|
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
tra[i] = m->l.elem[i];
|
tra[i] = m->l[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
srand(0);
|
srand(0);
|
||||||
|
@ -635,7 +635,7 @@ void SKdNode::SnapToVertex(Vector v, SMesh *extras) {
|
||||||
void SKdNode::SnapToMesh(SMesh *m) {
|
void SKdNode::SnapToMesh(SMesh *m) {
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(i = 0; i < m->l.n; i++) {
|
||||||
STriangle *tr = &(m->l.elem[i]);
|
STriangle *tr = &(m->l[i]);
|
||||||
if(tr->IsDegenerate()) {
|
if(tr->IsDegenerate()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -647,7 +647,7 @@ void SKdNode::SnapToMesh(SMesh *m) {
|
||||||
|
|
||||||
for(k = 0; k < extra.l.n; k++) {
|
for(k = 0; k < extra.l.n; k++) {
|
||||||
STriangle *tra = (STriangle *)AllocTemporary(sizeof(*tra));
|
STriangle *tra = (STriangle *)AllocTemporary(sizeof(*tra));
|
||||||
*tra = extra.l.elem[k];
|
*tra = extra.l[k];
|
||||||
AddTriangle(tra);
|
AddTriangle(tra);
|
||||||
}
|
}
|
||||||
extra.Clear();
|
extra.Clear();
|
||||||
|
|
|
@ -98,7 +98,7 @@ void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
|
||||||
// that relationship. So put it back here now.
|
// that relationship. So put it back here now.
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < ld.n; 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();
|
ld.Clear();
|
||||||
}
|
}
|
||||||
|
@ -410,7 +410,7 @@ void GraphicsWindow::MakeTangentArc() {
|
||||||
// Delete the coincident constraint for the removed point.
|
// Delete the coincident constraint for the removed point.
|
||||||
SK.constraint.ClearTags();
|
SK.constraint.ClearTags();
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
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->group != activeGroup) continue;
|
||||||
if(cs->workplane != ActiveWorkplane()) continue;
|
if(cs->workplane != ActiveWorkplane()) continue;
|
||||||
if(cs->type != Constraint::Type::POINTS_COINCIDENT) continue;
|
if(cs->type != Constraint::Type::POINTS_COINCIDENT) continue;
|
||||||
|
@ -535,7 +535,7 @@ hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) {
|
||||||
double t;
|
double t;
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < sbl.l.n; i++) {
|
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");
|
ssassert(sb->deg == 3, "Expected a cubic bezier");
|
||||||
|
|
||||||
sb->ClosestPointTo(pinter, &t, /*mustConverge=*/false);
|
sb->ClosestPointTo(pinter, &t, /*mustConverge=*/false);
|
||||||
|
|
|
@ -227,7 +227,8 @@ bool SEdgeList::AssembleContour(Vector first, Vector last, SContour *dest,
|
||||||
|
|
||||||
do {
|
do {
|
||||||
for(i = 0; i < l.n; i++) {
|
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->tag) continue;
|
||||||
|
|
||||||
if(se->a.Equals(last)) {
|
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);
|
Vector last = Vector::From(0, 0, 0);
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
if(!l.elem[i].tag) {
|
if(!l[i].tag) {
|
||||||
first = l.elem[i].a;
|
first = l[i].a;
|
||||||
last = l.elem[i].b;
|
last = l[i].b;
|
||||||
l.elem[i].tag = 1;
|
/// @todo fix const!
|
||||||
|
const_cast<SEdge*>(&(l[i]))->tag = 1;
|
||||||
break;
|
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
|
// Create a new empty contour in our polygon, and finish assembling
|
||||||
// into that contour.
|
// into that contour.
|
||||||
dest->AddEmptyContour();
|
dest->AddEmptyContour();
|
||||||
if(!AssembleContour(first, last, &(dest->l.elem[dest->l.n-1]),
|
if(!AssembleContour(first, last, &(dest->l[dest->l.n-1]),
|
||||||
errorAt, keepDir))
|
errorAt, keepDir))
|
||||||
{
|
{
|
||||||
allClosed = false;
|
allClosed = false;
|
||||||
|
@ -337,9 +339,9 @@ void SEdgeList::CullExtraneousEdges(bool both) {
|
||||||
l.ClearTags();
|
l.ClearTags();
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SEdge *se = &(l.elem[i]);
|
SEdge *se = &(l[i]);
|
||||||
for(j = i+1; j < l.n; j++) {
|
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)) {
|
if((set->a).Equals(se->a) && (set->b).Equals(se->b)) {
|
||||||
// Two parallel edges exist; so keep only the first one.
|
// Two parallel edges exist; so keep only the first one.
|
||||||
set->tag = 1;
|
set->tag = 1;
|
||||||
|
@ -527,7 +529,7 @@ bool SPointList::ContainsPoint(Vector pt) const {
|
||||||
int SPointList::IndexForPoint(Vector pt) const {
|
int SPointList::IndexForPoint(Vector pt) const {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SPoint *p = &(l.elem[i]);
|
const SPoint *p = &(l[i]);
|
||||||
if(pt.Equals(p->p)) {
|
if(pt.Equals(p->p)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +569,7 @@ void SContour::AddPoint(Vector p) {
|
||||||
void SContour::MakeEdgesInto(SEdgeList *el) const {
|
void SContour::MakeEdgesInto(SEdgeList *el) const {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < (l.n - 1); 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);
|
Vector n = Vector::From(0, 0, 0);
|
||||||
|
|
||||||
for(int i = 0; i < l.n - 2; i++) {
|
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 u = (l[i+1].p).Minus(l[i+0].p).WithMagnitude(1);
|
||||||
Vector v = (l.elem[i+2].p).Minus(l.elem[i+1].p).WithMagnitude(1);
|
Vector v = (l[i+2].p).Minus(l[i+1].p).WithMagnitude(1);
|
||||||
Vector nt = u.Cross(v);
|
Vector nt = u.Cross(v);
|
||||||
if(nt.Magnitude() > n.Magnitude()) {
|
if(nt.Magnitude() > n.Magnitude()) {
|
||||||
n = nt;
|
n = nt;
|
||||||
|
@ -602,7 +604,7 @@ Vector SContour::ComputeNormal() const {
|
||||||
|
|
||||||
Vector SContour::AnyEdgeMidpoint() const {
|
Vector SContour::AnyEdgeMidpoint() const {
|
||||||
ssassert(l.n >= 2, "Need two points to find a midpoint");
|
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 {
|
bool SContour::IsClockwiseProjdToNormal(Vector n) const {
|
||||||
|
@ -620,10 +622,10 @@ double SContour::SignedAreaProjdToNormal(Vector n) const {
|
||||||
|
|
||||||
double area = 0;
|
double area = 0;
|
||||||
for(int i = 0; i < (l.n - 1); i++) {
|
for(int i = 0; i < (l.n - 1); i++) {
|
||||||
double u0 = (l.elem[i ].p).Dot(u);
|
double u0 = (l[i ].p).Dot(u);
|
||||||
double v0 = (l.elem[i ].p).Dot(v);
|
double v0 = (l[i ].p).Dot(v);
|
||||||
double u1 = (l.elem[i+1].p).Dot(u);
|
double u1 = (l[i+1].p).Dot(u);
|
||||||
double v1 = (l.elem[i+1].p).Dot(v);
|
double v1 = (l[i+1].p).Dot(v);
|
||||||
|
|
||||||
area += ((v0 + v1)/2)*(u1 - u0);
|
area += ((v0 + v1)/2)*(u1 - u0);
|
||||||
}
|
}
|
||||||
|
@ -639,11 +641,11 @@ bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) const {
|
||||||
|
|
||||||
bool inside = false;
|
bool inside = false;
|
||||||
for(int i = 0; i < (l.n - 1); i++) {
|
for(int i = 0; i < (l.n - 1); i++) {
|
||||||
double ua = (l.elem[i ].p).Dot(u);
|
double ua = (l[i ].p).Dot(u);
|
||||||
double va = (l.elem[i ].p).Dot(v);
|
double va = (l[i ].p).Dot(v);
|
||||||
// The curve needs to be exactly closed; approximation is death.
|
// The curve needs to be exactly closed; approximation is death.
|
||||||
double ub = (l.elem[(i+1)%(l.n-1)].p).Dot(u);
|
double ub = (l[(i+1)%(l.n-1)].p).Dot(u);
|
||||||
double vb = (l.elem[(i+1)%(l.n-1)].p).Dot(v);
|
double vb = (l[(i+1)%(l.n-1)].p).Dot(v);
|
||||||
|
|
||||||
if ((((va <= vp) && (vp < vb)) ||
|
if ((((va <= vp) && (vp < vb)) ||
|
||||||
((vb <= vp) && (vp < va))) &&
|
((vb <= vp) && (vp < va))) &&
|
||||||
|
@ -664,7 +666,7 @@ void SContour::Reverse() {
|
||||||
void SPolygon::Clear() {
|
void SPolygon::Clear() {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
(l.elem[i]).l.Clear();
|
(l[i]).l.Clear();
|
||||||
}
|
}
|
||||||
l.Clear();
|
l.Clear();
|
||||||
}
|
}
|
||||||
|
@ -677,13 +679,13 @@ void SPolygon::AddEmptyContour() {
|
||||||
void SPolygon::MakeEdgesInto(SEdgeList *el) const {
|
void SPolygon::MakeEdgesInto(SEdgeList *el) const {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
(l.elem[i]).MakeEdgesInto(el);
|
(l[i]).MakeEdgesInto(el);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector SPolygon::ComputeNormal() const {
|
Vector SPolygon::ComputeNormal() const {
|
||||||
if(l.n < 1) return Vector::From(0, 0, 0);
|
if(l.n < 1) return Vector::From(0, 0, 0);
|
||||||
return (l.elem[0]).ComputeNormal();
|
return (l[0]).ComputeNormal();
|
||||||
}
|
}
|
||||||
|
|
||||||
double SPolygon::SignedArea() const {
|
double SPolygon::SignedArea() const {
|
||||||
|
@ -704,7 +706,7 @@ int SPolygon::WindingNumberForPoint(Vector p) const {
|
||||||
int winding = 0;
|
int winding = 0;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SContour *sc = &(l.elem[i]);
|
const SContour *sc = &(l[i]);
|
||||||
if(sc->ContainsPointProjdToNormal(normal, p)) {
|
if(sc->ContainsPointProjdToNormal(normal, p)) {
|
||||||
winding++;
|
winding++;
|
||||||
}
|
}
|
||||||
|
@ -719,18 +721,18 @@ void SPolygon::FixContourDirections() {
|
||||||
// Outside curve looks counterclockwise, projected against our normal.
|
// Outside curve looks counterclockwise, projected against our normal.
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SContour *sc = &(l.elem[i]);
|
SContour *sc = &(l[i]);
|
||||||
if(sc->l.n < 2) continue;
|
if(sc->l.n < 2) continue;
|
||||||
// The contours may not intersect, but they may share vertices; so
|
// The contours may not intersect, but they may share vertices; so
|
||||||
// testing a vertex for point-in-polygon may fail, but the midpoint
|
// testing a vertex for point-in-polygon may fail, but the midpoint
|
||||||
// of an edge is okay.
|
// 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;
|
sc->timesEnclosed = 0;
|
||||||
bool outer = true;
|
bool outer = true;
|
||||||
for(j = 0; j < l.n; j++) {
|
for(j = 0; j < l.n; j++) {
|
||||||
if(i == j) continue;
|
if(i == j) continue;
|
||||||
SContour *sct = &(l.elem[j]);
|
SContour *sct = &(l[j]);
|
||||||
if(sct->ContainsPointProjdToNormal(normal, pt)) {
|
if(sct->ContainsPointProjdToNormal(normal, pt)) {
|
||||||
outer = !outer;
|
outer = !outer;
|
||||||
(sc->timesEnclosed)++;
|
(sc->timesEnclosed)++;
|
||||||
|
@ -753,7 +755,7 @@ bool SPolygon::IsEmpty() const {
|
||||||
|
|
||||||
Vector SPolygon::AnyPoint() const {
|
Vector SPolygon::AnyPoint() const {
|
||||||
ssassert(!IsEmpty(), "Need at least one point");
|
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 {
|
bool SPolygon::SelfIntersecting(Vector *intersectsAt) const {
|
||||||
|
@ -799,9 +801,9 @@ void SPolygon::OffsetInto(SPolygon *dest, double r) const {
|
||||||
int i;
|
int i;
|
||||||
dest->Clear();
|
dest->Clear();
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SContour *sc = &(l.elem[i]);
|
const SContour *sc = &(l[i]);
|
||||||
dest->AddEmptyContour();
|
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;
|
Vector dp, dn;
|
||||||
double thetan, thetap;
|
double thetan, thetap;
|
||||||
|
|
||||||
a = l.elem[WRAP(i-1, (l.n-1))].p;
|
a = l[WRAP(i-1, (l.n-1))].p;
|
||||||
b = l.elem[WRAP(i, (l.n-1))].p;
|
b = l[WRAP(i, (l.n-1))].p;
|
||||||
c = l.elem[WRAP(i+1, (l.n-1))].p;
|
c = l[WRAP(i+1, (l.n-1))].p;
|
||||||
|
|
||||||
dp = a.Minus(b);
|
dp = a.Minus(b);
|
||||||
thetap = atan2(dp.y, dp.x);
|
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];
|
MeshVertex *vertices = new MeshVertex[m.l.n * 3];
|
||||||
for(int i = 0; i < m.l.n; i++) {
|
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 + 0].pos = Vector3f::From(t.a);
|
||||||
vertices[i * 3 + 1].pos = Vector3f::From(t.b);
|
vertices[i * 3 + 1].pos = Vector3f::From(t.b);
|
||||||
vertices[i * 3 + 2].pos = Vector3f::From(t.c);
|
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 curVertex = 0;
|
||||||
uint32_t curIndex = 0;
|
uint32_t curIndex = 0;
|
||||||
for(int i = 0; i < edges.l.n; i++) {
|
for(int i = 0; i < edges.l.n; i++) {
|
||||||
const SEdge &curr = edges.l.elem[i];
|
const SEdge &curr = edges.l[i];
|
||||||
const SEdge &next = edges.l.elem[(i + 1) % edges.l.n];
|
const SEdge &next = edges.l[(i + 1) % edges.l.n];
|
||||||
|
|
||||||
// 3d positions
|
// 3d positions
|
||||||
Vector3f a = Vector3f::From(curr.a);
|
Vector3f a = Vector3f::From(curr.a);
|
||||||
|
@ -674,8 +674,8 @@ OutlineRenderer::Handle OutlineRenderer::Add(const SOutlineList &outlines, bool
|
||||||
uint32_t curIndex = 0;
|
uint32_t curIndex = 0;
|
||||||
|
|
||||||
for(int i = 0; i < outlines.l.n; i++) {
|
for(int i = 0; i < outlines.l.n; i++) {
|
||||||
const SOutline &curr = outlines.l.elem[i];
|
const SOutline &curr = outlines.l[i];
|
||||||
const SOutline &next = outlines.l.elem[(i + 1) % outlines.l.n];
|
const SOutline &next = outlines.l[(i + 1) % outlines.l.n];
|
||||||
|
|
||||||
// 3d positions
|
// 3d positions
|
||||||
Vector3f a = Vector3f::From(curr.a);
|
Vector3f a = Vector3f::From(curr.a);
|
||||||
|
|
|
@ -243,7 +243,7 @@ void SurfaceRenderer::ConvertBeziersToEdges() {
|
||||||
List<Vector> lv = {};
|
List<Vector> lv = {};
|
||||||
b.MakePwlInto(&lv, chordTolerance);
|
b.MakePwlInto(&lv, chordTolerance);
|
||||||
for(int i = 1; i < lv.n; i++) {
|
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();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -777,7 +777,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
double vol = 0;
|
double vol = 0;
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < m->l.n; 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)
|
// Translate to place vertex A at (x, y, 0)
|
||||||
Vector trans = Vector::From(tr.a.x, tr.a.y, 0);
|
Vector trans = Vector::From(tr.a.x, tr.a.y, 0);
|
||||||
|
@ -907,7 +907,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
int i;
|
int i;
|
||||||
SContour *sc = &(SS.traced.path);
|
SContour *sc = &(SS.traced.path);
|
||||||
for(i = 0; i < sc->l.n; i++) {
|
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;
|
double s = SS.exportScale;
|
||||||
fprintf(f, "%.10f, %.10f, %.10f\r\n",
|
fprintf(f, "%.10f, %.10f, %.10f\r\n",
|
||||||
p.x/s, p.y/s, p.z/s);
|
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");
|
ssassert(!src->l.IsEmpty(), "Need at least one edge");
|
||||||
// Start with an arbitrary edge.
|
// Start with an arbitrary edge.
|
||||||
dest->l.Add(&(src->l.elem[0]));
|
dest->l.Add(&(src->l[0]));
|
||||||
src->l.ClearTags();
|
src->l.ClearTags();
|
||||||
src->l.elem[0].tag = 1;
|
src->l[0].tag = 1;
|
||||||
|
|
||||||
bool added;
|
bool added;
|
||||||
do {
|
do {
|
||||||
added = false;
|
added = false;
|
||||||
// The start and finish of the current edge chain
|
// The start and finish of the current edge chain
|
||||||
Vector s = dest->l.elem[0].a,
|
Vector s = dest->l[0].a,
|
||||||
f = dest->l.elem[dest->l.n - 1].b;
|
f = dest->l[dest->l.n - 1].b;
|
||||||
|
|
||||||
// We can attach a new edge at the start or finish, as long as that
|
// We can attach a new edge at the start or finish, as long as that
|
||||||
// start or finish point isn't in the list of points to avoid.
|
// start or finish point isn't in the list of points to avoid.
|
||||||
|
@ -445,8 +445,8 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < sc->pts.n; i++) {
|
for(i = 1; i < sc->pts.n; i++) {
|
||||||
Vector a = sc->pts.elem[i-1].p,
|
Vector a = sc->pts[i-1].p,
|
||||||
b = sc->pts.elem[i].p;
|
b = sc->pts[i].p;
|
||||||
|
|
||||||
Point2d auv, buv;
|
Point2d auv, buv;
|
||||||
ss->ClosestPointTo(a, &(auv.x), &(auv.y));
|
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
|
// Arbitrarily choose an edge within the chain to classify; they
|
||||||
// should all be the same, though.
|
// 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(),
|
Point2d auv = (se->a).ProjectXy(),
|
||||||
buv = (se->b).ProjectXy();
|
buv = (se->b).ProjectXy();
|
||||||
|
@ -545,7 +545,7 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
||||||
FindChainAvoiding(&inter, &chain, &choosing);
|
FindChainAvoiding(&inter, &chain, &choosing);
|
||||||
|
|
||||||
// Any edge in the chain, same as above.
|
// 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(),
|
Point2d auv = (se->a).ProjectXy(),
|
||||||
buv = (se->b).ProjectXy();
|
buv = (se->b).ProjectXy();
|
||||||
|
|
|
@ -239,12 +239,12 @@ void SBezierList::CullIdenticalBeziers(bool both) {
|
||||||
|
|
||||||
l.ClearTags();
|
l.ClearTags();
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
SBezier *bi = &(l.elem[i]), bir;
|
SBezier *bi = &(l[i]), bir;
|
||||||
bir = *bi;
|
bir = *bi;
|
||||||
bir.Reverse();
|
bir.Reverse();
|
||||||
|
|
||||||
for(j = i + 1; j < l.n; j++) {
|
for(j = i + 1; j < l.n; j++) {
|
||||||
SBezier *bj = &(l.elem[j]);
|
SBezier *bj = &(l[j]);
|
||||||
if(bj->Equals(bi) ||
|
if(bj->Equals(bi) ||
|
||||||
bj->Equals(&bir))
|
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.
|
// Get any point on any Bezier; or an arbitrary point if list is empty.
|
||||||
if(!l.IsEmpty()) {
|
if(!l.IsEmpty()) {
|
||||||
pt = l.elem[0].Start();
|
pt = l[0].Start();
|
||||||
} else {
|
} else {
|
||||||
pt = Vector::From(0, 0, 0);
|
pt = Vector::From(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -393,7 +393,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
|
||||||
if(sbl->l.n < 1) return loop;
|
if(sbl->l.n < 1) return loop;
|
||||||
sbl->l.ClearTags();
|
sbl->l.ClearTags();
|
||||||
|
|
||||||
SBezier *first = &(sbl->l.elem[0]);
|
SBezier *first = &(sbl->l[0]);
|
||||||
first->tag = 1;
|
first->tag = 1;
|
||||||
loop.l.Add(first);
|
loop.l.Add(first);
|
||||||
Vector start = first->Start();
|
Vector start = first->Start();
|
||||||
|
@ -406,7 +406,7 @@ SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl,
|
||||||
int i;
|
int i;
|
||||||
bool foundNext = false;
|
bool foundNext = false;
|
||||||
for(i = 0; i < sbl->l.n; i++) {
|
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) {
|
if((test->Finish()).Equals(hanging) && test->auxA == auxA) {
|
||||||
test->Reverse();
|
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.
|
// 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)) {
|
if((sc->l[sc->l.n - 1].p).Equals(sc->l[0].p)) {
|
||||||
sc->l.elem[sc->l.n - 1] = sc->l.elem[0];
|
sc->l[sc->l.n - 1] = sc->l[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SBezierLoop::IsClosed() const {
|
bool SBezierLoop::IsClosed() const {
|
||||||
if(l.n < 1) return false;
|
if(l.n < 1) return false;
|
||||||
Vector s = l.elem[0].Start(),
|
Vector s = l[0].Start(),
|
||||||
f = l.elem[l.n-1].Finish();
|
f = l[l.n-1].Finish();
|
||||||
return s.Equals(f);
|
return s.Equals(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ SBezierLoopSet SBezierLoopSet::From(SBezierList *sbl, SPolygon *poly,
|
||||||
} else {
|
} else {
|
||||||
ret.l.Add(&loop);
|
ret.l.Add(&loop);
|
||||||
poly->AddEmptyContour();
|
poly->AddEmptyContour();
|
||||||
loop.MakePwlInto(&(poly->l.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 {
|
void SBezierLoopSet::MakePwlInto(SPolygon *sp) const {
|
||||||
for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) {
|
for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) {
|
||||||
sp->AddEmptyContour();
|
sp->AddEmptyContour();
|
||||||
sbl->MakePwlInto(&(sp->l.elem[sp->l.n - 1]));
|
sbl->MakePwlInto(&(sp->l[sp->l.n - 1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SBezierLoopSet::Clear() {
|
void SBezierLoopSet::Clear() {
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
(l.elem[i]).Clear();
|
(l[i]).Clear();
|
||||||
}
|
}
|
||||||
l.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)) {
|
for(pt = sc->l.First(); pt; pt = sc->l.NextAfter(pt)) {
|
||||||
double u, v;
|
double u, v;
|
||||||
srfuv->ClosestPointTo(pt->p, &u, &v);
|
srfuv->ClosestPointTo(pt->p, &u, &v);
|
||||||
spuv.l.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
|
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).
|
// works for curved surfaces too (important for STEP export).
|
||||||
spuv.FixContourDirections();
|
spuv.FixContourDirections();
|
||||||
for(i = 0; i < spuv.l.n; i++) {
|
for(i = 0; i < spuv.l.n; i++) {
|
||||||
SContour *contour = &(spuv.l.elem[i]);
|
SContour *contour = &(spuv.l[i]);
|
||||||
SBezierLoop *bl = &(sbls.l.elem[i]);
|
SBezierLoop *bl = &(sbls.l[i]);
|
||||||
if(contour->tag) {
|
if(contour->tag) {
|
||||||
// This contour got reversed in the polygon to make the directions
|
// This contour got reversed in the polygon to make the directions
|
||||||
// consistent, so the same must be necessary for the Bezier loop.
|
// consistent, so the same must be necessary for the Bezier loop.
|
||||||
|
@ -648,7 +648,7 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
|
||||||
while(loopsRemaining) {
|
while(loopsRemaining) {
|
||||||
loopsRemaining = false;
|
loopsRemaining = false;
|
||||||
for(i = 0; i < sbls.l.n; i++) {
|
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;
|
if(loop->tag != OUTER_LOOP) continue;
|
||||||
|
|
||||||
// Check if this contour contains any outer loops; if it does, then
|
// 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
|
// will steal their holes, since their holes also lie inside this
|
||||||
// contour.
|
// contour.
|
||||||
for(j = 0; j < sbls.l.n; j++) {
|
for(j = 0; j < sbls.l.n; j++) {
|
||||||
SBezierLoop *outer = &(sbls.l.elem[j]);
|
SBezierLoop *outer = &(sbls.l[j]);
|
||||||
if(i == j) continue;
|
if(i == j) continue;
|
||||||
if(outer->tag != OUTER_LOOP) continue;
|
if(outer->tag != OUTER_LOOP) continue;
|
||||||
|
|
||||||
Vector p = spuv.l.elem[j].AnyEdgeMidpoint();
|
Vector p = spuv.l[j].AnyEdgeMidpoint();
|
||||||
if(spuv.l.elem[i].ContainsPointProjdToNormal(spuv.normal, p)) {
|
if(spuv.l[i].ContainsPointProjdToNormal(spuv.normal, p)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -675,16 +675,16 @@ void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz,
|
||||||
loop->tag = USED_LOOP;
|
loop->tag = USED_LOOP;
|
||||||
outerAndInners.l.Add(loop);
|
outerAndInners.l.Add(loop);
|
||||||
int auxA = 0;
|
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++) {
|
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->tag != INNER_LOOP) continue;
|
||||||
if(inner->l.n < 1) 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();
|
Vector p = spuv.l[j].AnyEdgeMidpoint();
|
||||||
if(spuv.l.elem[i].ContainsPointProjdToNormal(spuv.normal, p)) {
|
if(spuv.l[i].ContainsPointProjdToNormal(spuv.normal, p)) {
|
||||||
outerAndInners.l.Add(inner);
|
outerAndInners.l.Add(inner);
|
||||||
inner->tag = USED_LOOP;
|
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.
|
// to screw up on that stuff. So just add them onto the open curve list.
|
||||||
// Very ugly, but better than losing curves.
|
// Very ugly, but better than losing curves.
|
||||||
for(i = 0; i < sbls.l.n; i++) {
|
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(loop->tag == USED_LOOP) continue;
|
||||||
|
|
||||||
if(openContours) {
|
if(openContours) {
|
||||||
|
@ -804,11 +804,11 @@ void SCurve::RemoveShortSegments(SSurface *srfA, SSurface *srfB) {
|
||||||
if(pts.n <= 3) return;
|
if(pts.n <= 3) return;
|
||||||
pts.ClearTags();
|
pts.ClearTags();
|
||||||
|
|
||||||
Vector prev = pts.elem[0].p;
|
Vector prev = pts[0].p;
|
||||||
int i, a;
|
int i, a;
|
||||||
for(i = 1; i < pts.n - 1; i++) {
|
for(i = 1; i < pts.n - 1; i++) {
|
||||||
SCurvePt *sct = &(pts.elem[i]),
|
SCurvePt *sct = &(pts[i]),
|
||||||
*scn = &(pts.elem[i+1]);
|
*scn = &(pts[i+1]);
|
||||||
if(sct->vertex) {
|
if(sct->vertex) {
|
||||||
prev = sct->p;
|
prev = sct->p;
|
||||||
continue;
|
continue;
|
||||||
|
@ -849,12 +849,12 @@ STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc, bool backwards) {
|
||||||
SCurve *sc = shell->curve.FindById(hsc);
|
SCurve *sc = shell->curve.FindById(hsc);
|
||||||
|
|
||||||
if(backwards) {
|
if(backwards) {
|
||||||
stb.finish = sc->pts.elem[0].p;
|
stb.finish = sc->pts[0].p;
|
||||||
stb.start = sc->pts.elem[sc->pts.n - 1].p;
|
stb.start = sc->pts[sc->pts.n - 1].p;
|
||||||
stb.backwards = true;
|
stb.backwards = true;
|
||||||
} else {
|
} else {
|
||||||
stb.start = sc->pts.elem[0].p;
|
stb.start = sc->pts[0].p;
|
||||||
stb.finish = sc->pts.elem[sc->pts.n - 1].p;
|
stb.finish = sc->pts[sc->pts.n - 1].p;
|
||||||
stb.backwards = false;
|
stb.backwards = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ void SShell::MergeCoincidentSurfaces() {
|
||||||
SSurface *si, *sj;
|
SSurface *si, *sj;
|
||||||
|
|
||||||
for(i = 0; i < surface.n; i++) {
|
for(i = 0; i < surface.n; i++) {
|
||||||
si = &(surface.elem[i]);
|
si = &(surface[i]);
|
||||||
if(si->tag) continue;
|
if(si->tag) continue;
|
||||||
// Let someone else clean up the empty surfaces; we can certainly merge
|
// 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.
|
// them, but we don't know how to calculate a reasonable bounding box.
|
||||||
|
@ -31,7 +31,7 @@ void SShell::MergeCoincidentSurfaces() {
|
||||||
mergedThisTime = false;
|
mergedThisTime = false;
|
||||||
|
|
||||||
for(j = i + 1; j < surface.n; j++) {
|
for(j = i + 1; j < surface.n; j++) {
|
||||||
sj = &(surface.elem[j]);
|
sj = &(surface[j]);
|
||||||
if(sj->tag) continue;
|
if(sj->tag) continue;
|
||||||
if(!sj->CoincidentWith(si, /*sameNormal=*/true)) continue;
|
if(!sj->CoincidentWith(si, /*sameNormal=*/true)) continue;
|
||||||
if(!sj->color.Equals(si->color)) continue;
|
if(!sj->color.Equals(si->color)) continue;
|
||||||
|
|
|
@ -231,7 +231,7 @@ void SBezier::MakePwlInto(SEdgeList *sel, double chordTol) const {
|
||||||
MakePwlInto(&lv, chordTol);
|
MakePwlInto(&lv, chordTol);
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < lv.n; 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();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ void SBezier::MakePwlInto(List<SCurvePt> *l, double chordTol) const {
|
||||||
for(i = 0; i < lv.n; i++) {
|
for(i = 0; i < lv.n; i++) {
|
||||||
SCurvePt scpt;
|
SCurvePt scpt;
|
||||||
scpt.tag = 0;
|
scpt.tag = 0;
|
||||||
scpt.p = lv.elem[i];
|
scpt.p = lv[i];
|
||||||
scpt.vertex = (i == 0) || (i == (lv.n - 1));
|
scpt.vertex = (i == 0) || (i == (lv.n - 1));
|
||||||
l->Add(&scpt);
|
l->Add(&scpt);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,7 @@ void SBezier::MakePwlInto(SContour *sc, double chordTol) const {
|
||||||
MakePwlInto(&lv, chordTol);
|
MakePwlInto(&lv, chordTol);
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < lv.n; i++) {
|
for(i = 0; i < lv.n; i++) {
|
||||||
sc->AddPoint(lv.elem[i]);
|
sc->AddPoint(lv[i]);
|
||||||
}
|
}
|
||||||
lv.Clear();
|
lv.Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,15 +342,15 @@ void SSurface::AllPointsIntersecting(Vector a, Vector b,
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < inters.n; i++) {
|
for(i = 0; i < inters.n; i++) {
|
||||||
for(j = i + 1; j < inters.n; j++) {
|
for(j = i + 1; j < inters.n; j++) {
|
||||||
if(inters.elem[i].p.Equals(inters.elem[j].p)) {
|
if(inters[i].p.Equals(inters[j].p)) {
|
||||||
inters.elem[j].tag = 1;
|
inters[j].tag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inters.RemoveTagged();
|
inters.RemoveTagged();
|
||||||
|
|
||||||
for(i = 0; i < inters.n; i++) {
|
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
|
// Make sure the point lies within the finite line segment
|
||||||
Vector pxyz = PointAt(puv.x, puv.y);
|
Vector pxyz = PointAt(puv.x, puv.y);
|
||||||
|
|
|
@ -235,7 +235,7 @@ void SSurface::MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags,
|
||||||
increment = 1;
|
increment = 1;
|
||||||
}
|
}
|
||||||
for(i = first; i != (last + increment); i += increment) {
|
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) {
|
if(flags == MakeAs::UV) {
|
||||||
ClosestPointTo(*pt, &u, &v);
|
ClosestPointTo(*pt, &u, &v);
|
||||||
|
@ -343,11 +343,11 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
|
||||||
|
|
||||||
int sp, fp;
|
int sp, fp;
|
||||||
for(sp = 0; sp < sc->pts.n; sp++) {
|
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;
|
if(sp >= sc->pts.n) return;
|
||||||
for(fp = sp; fp < sc->pts.n; fp++) {
|
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;
|
if(fp >= sc->pts.n) return;
|
||||||
// So now the curve we want goes from elem[sp] to elem[fp]
|
// 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(;;) {
|
for(;;) {
|
||||||
// So construct a cubic Bezier with the correct endpoints
|
// So construct a cubic Bezier with the correct endpoints
|
||||||
// and tangents for the current span.
|
// and tangents for the current span.
|
||||||
Vector st = sc->pts.elem[sp].p,
|
Vector st = sc->pts[sp].p,
|
||||||
ft = sc->pts.elem[fpt].p,
|
ft = sc->pts[fpt].p,
|
||||||
sf = ft.Minus(st);
|
sf = ft.Minus(st);
|
||||||
double m = sf.Magnitude() / 3;
|
double m = sf.Magnitude() / 3;
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *
|
||||||
int i;
|
int i;
|
||||||
bool tooFar = false;
|
bool tooFar = false;
|
||||||
for(i = sp + 1; i <= (fpt - 1); i++) {
|
for(i = sp + 1; i <= (fpt - 1); i++) {
|
||||||
Vector p = sc->pts.elem[i].p;
|
Vector p = sc->pts[i].p;
|
||||||
double t;
|
double t;
|
||||||
sb.ClosestPointTo(p, &t, /*mustConverge=*/false);
|
sb.ClosestPointTo(p, &t, /*mustConverge=*/false);
|
||||||
Vector pp = sb.PointAt(t);
|
Vector pp = sb.PointAt(t);
|
||||||
|
@ -435,7 +435,7 @@ void SSurface::TriangulateInto(SShell *shell, SMesh *sm) {
|
||||||
|
|
||||||
STriMeta meta = { face, color };
|
STriMeta meta = { face, color };
|
||||||
for(i = start; i < sm->l.n; i++) {
|
for(i = start; i < sm->l.n; i++) {
|
||||||
STriangle *st = &(sm->l.elem[i]);
|
STriangle *st = &(sm->l[i]);
|
||||||
st->meta = meta;
|
st->meta = meta;
|
||||||
st->an = NormalAt(st->a.x, st->a.y);
|
st->an = NormalAt(st->a.x, st->a.y);
|
||||||
st->bn = NormalAt(st->b.x, st->b.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;
|
int i;
|
||||||
for(i = 0; i < trimLines.n; i++) {
|
for(i = 0; i < trimLines.n; i++) {
|
||||||
TrimLine *tl = &(trimLines.elem[i]);
|
TrimLine *tl = &(trimLines[i]);
|
||||||
SSurface *ss = surface.FindById(tl->hs);
|
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;
|
STrimBy stb;
|
||||||
stb = STrimBy::EntireCurve(this, tl->hc, /*backwards=*/true);
|
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
|
// Still the same loop. Need to create trim curves
|
||||||
for(i = 0; i < sbl->l.n; i++) {
|
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
|
// we generate one more curve than we did surfaces
|
||||||
for(j = 0; j <= sections; j++) {
|
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++) {
|
for(i = 0; i < sbl->l.n; i++) {
|
||||||
Revolved revs = hsl.elem[i],
|
Revolved revs = hsl[i],
|
||||||
revsp = hsl.elem[WRAP(i-1, sbl->l.n)];
|
revsp = hsl[WRAP(i-1, sbl->l.n)];
|
||||||
|
|
||||||
sb = &(sbl->l.elem[i]);
|
sb = &(sbl->l[i]);
|
||||||
|
|
||||||
for(j = 0; j < 4; j++) {
|
for(j = 0; j < 4; j++) {
|
||||||
SCurve sc;
|
SCurve sc;
|
||||||
|
@ -925,7 +925,7 @@ void SShell::MakeFirstOrderRevolvedSurfaces(Vector pt, Vector axis, int i0) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = i0; i < surface.n; 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
|
// Revolution of a line; this is potentially a plane, which we can
|
||||||
// rewrite to have degree (1, 1).
|
// rewrite to have degree (1, 1).
|
||||||
|
|
|
@ -277,7 +277,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < lv.n - 1; 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)));
|
pa = pa.Minus(axis.ScaledBy(pa.Dot(axis)));
|
||||||
pb = pb.Minus(axis.ScaledBy(pb.Dot(axis)));
|
pb = pb.Minus(axis.ScaledBy(pb.Dot(axis)));
|
||||||
pa = pa.Plus(axisc);
|
pa = pa.Plus(axisc);
|
||||||
|
@ -369,10 +369,10 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
||||||
sc.isExact = false;
|
sc.isExact = false;
|
||||||
sc.source = SCurve::Source::INTERSECTION;
|
sc.source = SCurve::Source::INTERSECTION;
|
||||||
|
|
||||||
Vector start = spl.l.elem[0].p,
|
Vector start = spl.l[0].p,
|
||||||
startv = spl.l.elem[0].auxv;
|
startv = spl.l[0].auxv;
|
||||||
spl.l.ClearTags();
|
spl.l.ClearTags();
|
||||||
spl.l.elem[0].tag = 1;
|
spl.l[0].tag = 1;
|
||||||
spl.l.RemoveTagged();
|
spl.l.RemoveTagged();
|
||||||
|
|
||||||
// Our chord tolerance is whatever the user specified
|
// Our chord tolerance is whatever the user specified
|
||||||
|
|
|
@ -114,7 +114,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
// point.
|
// point.
|
||||||
int sco = 0;
|
int sco = 0;
|
||||||
for(i = 0; i < (sc->l.n - 1); i++) {
|
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;
|
sco = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
int thiso = 0;
|
int thiso = 0;
|
||||||
double dmin = 1e10;
|
double dmin = 1e10;
|
||||||
for(i = 0; i < l.n; i++) {
|
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();
|
double d = (p.Minus(sc->xminPt)).MagSquared();
|
||||||
if(d < dmin) {
|
if(d < dmin) {
|
||||||
dmin = d;
|
dmin = d;
|
||||||
|
@ -140,7 +140,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
// merge them there, without a bridge.
|
// merge them there, without a bridge.
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
thisp = WRAP(i+thiso, l.n);
|
thisp = WRAP(i+thiso, l.n);
|
||||||
a = l.elem[thisp].p;
|
a = l[thisp].p;
|
||||||
|
|
||||||
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
|
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
|
||||||
if(f->Equals(a)) break;
|
if(f->Equals(a)) break;
|
||||||
|
@ -149,7 +149,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
|
|
||||||
for(j = 0; j < (sc->l.n - 1); j++) {
|
for(j = 0; j < (sc->l.n - 1); j++) {
|
||||||
scp = WRAP(j+sco, (sc->l.n - 1));
|
scp = WRAP(j+sco, (sc->l.n - 1));
|
||||||
b = sc->l.elem[scp].p;
|
b = sc->l[scp].p;
|
||||||
|
|
||||||
if(a.Equals(b)) {
|
if(a.Equals(b)) {
|
||||||
goto haveEdge;
|
goto haveEdge;
|
||||||
|
@ -160,7 +160,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
// If that fails, look for a bridge that does not intersect any edges.
|
// If that fails, look for a bridge that does not intersect any edges.
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
thisp = WRAP(i+thiso, l.n);
|
thisp = WRAP(i+thiso, l.n);
|
||||||
a = l.elem[thisp].p;
|
a = l[thisp].p;
|
||||||
|
|
||||||
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
|
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
|
||||||
if(f->Equals(a)) break;
|
if(f->Equals(a)) break;
|
||||||
|
@ -169,7 +169,7 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
|
|
||||||
for(j = 0; j < (sc->l.n - 1); j++) {
|
for(j = 0; j < (sc->l.n - 1); j++) {
|
||||||
scp = WRAP(j+sco, (sc->l.n - 1));
|
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)) {
|
for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) {
|
||||||
if(f->Equals(b)) break;
|
if(f->Equals(b)) break;
|
||||||
|
@ -190,15 +190,15 @@ bool SContour::BridgeToContour(SContour *sc,
|
||||||
haveEdge:
|
haveEdge:
|
||||||
SContour merged = {};
|
SContour merged = {};
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
merged.AddPoint(l.elem[i].p);
|
merged.AddPoint(l[i].p);
|
||||||
if(i == thisp) {
|
if(i == thisp) {
|
||||||
// less than or equal; need to duplicate the join point
|
// less than or equal; need to duplicate the join point
|
||||||
for(j = 0; j <= (sc->l.n - 1); j++) {
|
for(j = 0; j <= (sc->l.n - 1); j++) {
|
||||||
int jp = WRAP(j + scp, (sc->l.n - 1));
|
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
|
// 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);
|
cp = WRAP(bp+1, l.n);
|
||||||
|
|
||||||
STriangle tr = {};
|
STriangle tr = {};
|
||||||
tr.a = l.elem[ap].p;
|
tr.a = l[ap].p;
|
||||||
tr.b = l.elem[bp].p;
|
tr.b = l[bp].p;
|
||||||
tr.c = l.elem[cp].p;
|
tr.c = l[cp].p;
|
||||||
|
|
||||||
if((tr.a).Equals(tr.c)) {
|
if((tr.a).Equals(tr.c)) {
|
||||||
// This is two coincident and anti-parallel edges. Zero-area, so
|
// 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++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
if(i == ap || i == bp || i == cp) continue;
|
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;
|
if(p.OutsideAndNotOn(maxv, minv)) continue;
|
||||||
|
|
||||||
// A point on the edge of the triangle is considered to be inside,
|
// 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);
|
cp = WRAP(bp+1, l.n);
|
||||||
|
|
||||||
STriangle tr = {};
|
STriangle tr = {};
|
||||||
tr.a = l.elem[ap].p;
|
tr.a = l[ap].p;
|
||||||
tr.b = l.elem[bp].p;
|
tr.b = l[bp].p;
|
||||||
tr.c = l.elem[cp].p;
|
tr.c = l[cp].p;
|
||||||
if(tr.Normal().MagSquared() < scaledEps*scaledEps) {
|
if(tr.Normal().MagSquared() < scaledEps*scaledEps) {
|
||||||
// A vertex with more than two edges will cause us to generate
|
// A vertex with more than two edges will cause us to generate
|
||||||
// zero-area triangles, which must be culled.
|
// 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
|
// By deleting the point at bp, we may change the ear-ness of the points
|
||||||
// on either side.
|
// on either side.
|
||||||
l.elem[ap].ear = EarType::UNKNOWN;
|
l[ap].ear = EarType::UNKNOWN;
|
||||||
l.elem[cp].ear = EarType::UNKNOWN;
|
l[cp].ear = EarType::UNKNOWN;
|
||||||
|
|
||||||
l.ClearTags();
|
l.ClearTags();
|
||||||
l.elem[bp].tag = 1;
|
l[bp].tag = 1;
|
||||||
l.RemoveTagged();
|
l.RemoveTagged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,23 +299,23 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
|
||||||
// Clean the original contour by removing any zero-length edges.
|
// Clean the original contour by removing any zero-length edges.
|
||||||
l.ClearTags();
|
l.ClearTags();
|
||||||
for(i = 1; i < l.n; i++) {
|
for(i = 1; i < l.n; i++) {
|
||||||
if((l.elem[i].p).Equals(l.elem[i-1].p)) {
|
if((l[i].p).Equals(l[i-1].p)) {
|
||||||
l.elem[i].tag = 1;
|
l[i].tag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l.RemoveTagged();
|
l.RemoveTagged();
|
||||||
|
|
||||||
// Now calculate the ear-ness of each vertex
|
// Now calculate the ear-ness of each vertex
|
||||||
for(i = 0; i < l.n; i++) {
|
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;
|
bool toggle = false;
|
||||||
while(l.n > 3) {
|
while(l.n > 3) {
|
||||||
// Some points may have changed ear-ness, so recalculate
|
// Some points may have changed ear-ness, so recalculate
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
if(l.elem[i].ear == EarType::UNKNOWN) {
|
if(l[i].ear == EarType::UNKNOWN) {
|
||||||
(l.elem[i]).ear = IsEar(i, scaledEps) ?
|
(l[i]).ear = IsEar(i, scaledEps) ?
|
||||||
EarType::EAR : EarType::NOT_EAR;
|
EarType::EAR : EarType::NOT_EAR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,7 +328,7 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
|
||||||
int offset = toggle ? -1 : 0;
|
int offset = toggle ? -1 : 0;
|
||||||
for(i = 0; i < l.n; i++) {
|
for(i = 0; i < l.n; i++) {
|
||||||
int ear = WRAP(i+offset, l.n);
|
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) {
|
if(srf->degm == 1 && srf->degn == 1) {
|
||||||
// This is a plane; any ear is a good ear.
|
// This is a plane; any ear is a good ear.
|
||||||
bestEar = ear;
|
bestEar = ear;
|
||||||
|
@ -337,8 +337,8 @@ void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) {
|
||||||
// If we are triangulating a curved surface, then try to
|
// If we are triangulating a curved surface, then try to
|
||||||
// clip ears that have a small chord tolerance from the
|
// clip ears that have a small chord tolerance from the
|
||||||
// surface.
|
// surface.
|
||||||
Vector prev = l.elem[WRAP((i+offset-1), l.n)].p,
|
Vector prev = l[WRAP((i+offset-1), l.n)].p,
|
||||||
next = l.elem[WRAP((i+offset+1), l.n)].p;
|
next = l[WRAP((i+offset+1), l.n)].p;
|
||||||
double tol = srf->ChordToleranceForEdge(prev, next);
|
double tol = srf->ChordToleranceForEdge(prev, next);
|
||||||
if(tol < bestChordTol - scaledEps) {
|
if(tol < bestChordTol - scaledEps) {
|
||||||
bestEar = ear;
|
bestEar = ear;
|
||||||
|
@ -444,8 +444,8 @@ void SPolygon::UvGridTriangulateInto(SMesh *mesh, SSurface *srf) {
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < (li.n - 1); i++) {
|
for(i = 0; i < (li.n - 1); i++) {
|
||||||
for(j = 0; j < (lj.n - 1); j++) {
|
for(j = 0; j < (lj.n - 1); j++) {
|
||||||
double us = li.elem[i], uf = li.elem[i+1],
|
double us = li[i], uf = li[i+1],
|
||||||
vs = lj.elem[j], vf = lj.elem[j+1];
|
vs = lj[j], vf = lj[j+1];
|
||||||
|
|
||||||
Vector a = Vector::From(us, vs, 0),
|
Vector a = Vector::From(us, vs, 0),
|
||||||
b = Vector::From(us, vf, 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);
|
dbp("%d equations", eq.n);
|
||||||
for(i = 0; i < eq.n; i++) {
|
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);
|
dbp("%d parameters", param.n);
|
||||||
for(i = 0; i < param.n; i++) {
|
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.
|
// 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++) {
|
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);
|
Constraint *c = SK.constraint.FindByIdNoOops(hc);
|
||||||
if(!c) continue;
|
if(!c) continue;
|
||||||
|
|
||||||
|
|
|
@ -72,14 +72,14 @@ void TtfFontList::LoadAll() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort fonts according to their actual name, not filename.
|
// 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; });
|
[](const TtfFont &a, const TtfFont &b) { return a.name < b.name; });
|
||||||
|
|
||||||
// Filter out fonts with the same family and style name. This is not
|
// 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.
|
// 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; });
|
[](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
|
// TODO: identify fonts by their name and not filename, which may change
|
||||||
// between OSes.
|
// between OSes.
|
||||||
|
|
Loading…
Reference in New Issue