Convert many loops to range-for or std algorithms. NFC.
Also add comments about indexing and when we don't use range-for.
This commit is contained in:
parent
97c8cb7d71
commit
86f20cc7e5
13
src/bsp.cpp
13
src/bsp.cpp
@ -12,13 +12,8 @@ SBsp2 *SBsp2::Alloc() { return (SBsp2 *)AllocTemporary(sizeof(SBsp2)); }
|
|||||||
SBsp3 *SBsp3::Alloc() { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); }
|
SBsp3 *SBsp3::Alloc() { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); }
|
||||||
|
|
||||||
SBsp3 *SBsp3::FromMesh(const SMesh *m) {
|
SBsp3 *SBsp3::FromMesh(const SMesh *m) {
|
||||||
SBsp3 *bsp3 = NULL;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
SMesh mc = {};
|
SMesh mc = {};
|
||||||
for(i = 0; i < m->l.n; i++) {
|
for(auto const &elt : m->l) { mc.AddTriangle(&elt); }
|
||||||
mc.AddTriangle(&(m->l.elem[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
srand(0); // Let's be deterministic, at least!
|
srand(0); // Let's be deterministic, at least!
|
||||||
int n = mc.l.n;
|
int n = mc.l.n;
|
||||||
@ -28,10 +23,8 @@ SBsp3 *SBsp3::FromMesh(const SMesh *m) {
|
|||||||
swap(mc.l.elem[k], mc.l.elem[n]);
|
swap(mc.l.elem[k], mc.l.elem[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < mc.l.n; i++) {
|
SBsp3 *bsp3 = NULL;
|
||||||
bsp3 = InsertOrCreate(bsp3, &(mc.l.elem[i]), NULL);
|
for(auto &elt : mc.l) { bsp3 = InsertOrCreate(bsp3, &elt, NULL); }
|
||||||
}
|
|
||||||
|
|
||||||
mc.Clear();
|
mc.Clear();
|
||||||
return bsp3;
|
return bsp3;
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ std::string Constraint::DescriptionString() const {
|
|||||||
void Constraint::DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA)
|
void Constraint::DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA)
|
||||||
{
|
{
|
||||||
SK.constraint.ClearTags();
|
SK.constraint.ClearTags();
|
||||||
for(int i = 0; i < SK.constraint.n; i++) {
|
for(auto &constraint : SK.constraint) {
|
||||||
ConstraintBase *ct = &(SK.constraint.elem[i]);
|
ConstraintBase *ct = &constraint;
|
||||||
if(ct->type != type) continue;
|
if(ct->type != type) continue;
|
||||||
|
|
||||||
if(ct->entityA != entityA) continue;
|
if(ct->entityA != entityA) continue;
|
||||||
|
@ -434,10 +434,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ClearTags() {
|
void ClearTags() {
|
||||||
int i;
|
for(auto &elt : *this) { elt.tag = 0; }
|
||||||
for(i = 0; i < n; i++) {
|
|
||||||
elem[i].tag = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tag(H h, int tag) {
|
void Tag(H h, int tag) {
|
||||||
|
@ -922,19 +922,16 @@ void EntityBase::GenerateEquations(IdList<Equation,hEquation> *l) const {
|
|||||||
// If the two endpoints of the arc are constrained coincident
|
// If the two endpoints of the arc are constrained coincident
|
||||||
// (to make a complete circle), then our distance constraint
|
// (to make a complete circle), then our distance constraint
|
||||||
// would be redundant and therefore overconstrain things.
|
// would be redundant and therefore overconstrain things.
|
||||||
int i;
|
auto it = std::find_if(SK.constraint.begin(), SK.constraint.end(),
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
[&](ConstraintBase const &con) {
|
||||||
ConstraintBase *c = &(SK.constraint.elem[i]);
|
return (con.group == group) &&
|
||||||
if(c->group != group) continue;
|
(con.type == Constraint::Type::POINTS_COINCIDENT) &&
|
||||||
if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
|
((con.ptA == point[1] && con.ptB == point[2]) ||
|
||||||
|
(con.ptA == point[2] && con.ptB == point[1]));
|
||||||
if((c->ptA == point[1] && c->ptB == point[2]) ||
|
});
|
||||||
(c->ptA == point[2] && c->ptB == point[1]))
|
if(it != SK.constraint.end()) {
|
||||||
{
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(i < SK.constraint.n) break;
|
|
||||||
|
|
||||||
Expr *ra = Constraint::Distance(workplane, point[0], point[1]);
|
Expr *ra = Constraint::Distance(workplane, point[0], point[1]);
|
||||||
Expr *rb = Constraint::Distance(workplane, point[0], point[2]);
|
Expr *rb = Constraint::Distance(workplane, point[0], point[2]);
|
||||||
|
@ -96,9 +96,8 @@ void SolveSpaceUI::ExportSectionTo(const Platform::Path &filename) {
|
|||||||
bl.CullIdenticalBeziers(/*both=*/true);
|
bl.CullIdenticalBeziers(/*both=*/true);
|
||||||
|
|
||||||
// Collect lines and beziers with custom style & export.
|
// Collect lines and beziers with custom style & export.
|
||||||
int i;
|
for(auto &ent : SK.entity) {
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
Entity *e = &ent;
|
||||||
Entity *e = &(SK.entity.elem[i]);
|
|
||||||
if (!e->IsVisible()) continue;
|
if (!e->IsVisible()) continue;
|
||||||
if (e->style.v < Style::FIRST_CUSTOM) continue;
|
if (e->style.v < Style::FIRST_CUSTOM) continue;
|
||||||
if (!Style::Exportable(e->style.v)) continue;
|
if (!Style::Exportable(e->style.v)) continue;
|
||||||
@ -186,7 +185,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void SolveSpaceUI::ExportViewOrWireframeTo(const Platform::Path &filename, bool exportWireframe) {
|
void SolveSpaceUI::ExportViewOrWireframeTo(const Platform::Path &filename, bool exportWireframe) {
|
||||||
int i;
|
|
||||||
SEdgeList edges = {};
|
SEdgeList edges = {};
|
||||||
SBezierList beziers = {};
|
SBezierList beziers = {};
|
||||||
|
|
||||||
@ -206,8 +204,8 @@ void SolveSpaceUI::ExportViewOrWireframeTo(const Platform::Path &filename, bool
|
|||||||
sm = NULL;
|
sm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
for(auto &entity : SK.entity) {
|
||||||
Entity *e = &(SK.entity.elem[i]);
|
Entity *e = &entity;
|
||||||
if(!e->IsVisible()) continue;
|
if(!e->IsVisible()) continue;
|
||||||
if(e->construction) continue;
|
if(e->construction) continue;
|
||||||
|
|
||||||
|
@ -1027,8 +1027,9 @@ void SvgFileWriter::StartFile() {
|
|||||||
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000;
|
||||||
fprintf(f, "stroke-width:%f;\r\n", sw);
|
fprintf(f, "stroke-width:%f;\r\n", sw);
|
||||||
fprintf(f, "}\r\n");
|
fprintf(f, "}\r\n");
|
||||||
for(int i = 0; i < SK.style.n; i++) {
|
for(auto &style : SK.style) {
|
||||||
Style *s = &SK.style.elem[i];
|
Style *s = &style;
|
||||||
|
|
||||||
RgbaColor strokeRgb = Style::Color(s->h, /*forExport=*/true);
|
RgbaColor strokeRgb = Style::Color(s->h, /*forExport=*/true);
|
||||||
StipplePattern pattern = Style::PatternType(s->h);
|
StipplePattern pattern = Style::PatternType(s->h);
|
||||||
double stippleScale = Style::StippleScaleMm(s->h);
|
double stippleScale = Style::StippleScaleMm(s->h);
|
||||||
|
30
src/file.cpp
30
src/file.cpp
@ -20,8 +20,8 @@ void SolveSpaceUI::ClearExisting() {
|
|||||||
UndoClearStack(&redo);
|
UndoClearStack(&redo);
|
||||||
UndoClearStack(&undo);
|
UndoClearStack(&undo);
|
||||||
|
|
||||||
for(int i = 0; i < SK.groupOrder.n; i++) {
|
for(hGroup hg : SK.groupOrder) {
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
Group *g = SK.GetGroup(hg);
|
||||||
g->Clear();
|
g->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,39 +301,39 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
|
|||||||
fprintf(fh, "%s\n\n\n", VERSION_STRING);
|
fprintf(fh, "%s\n\n\n", VERSION_STRING);
|
||||||
|
|
||||||
int i, j;
|
int i, j;
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(auto &g : SK.group) {
|
||||||
sv.g = SK.group.elem[i];
|
sv.g = g;
|
||||||
SaveUsingTable(filename, 'g');
|
SaveUsingTable(filename, 'g');
|
||||||
fprintf(fh, "AddGroup\n\n");
|
fprintf(fh, "AddGroup\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.param.n; i++) {
|
for(auto &p : SK.param) {
|
||||||
sv.p = SK.param.elem[i];
|
sv.p = p;
|
||||||
SaveUsingTable(filename, 'p');
|
SaveUsingTable(filename, 'p');
|
||||||
fprintf(fh, "AddParam\n\n");
|
fprintf(fh, "AddParam\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
for(auto &r : SK.request) {
|
||||||
sv.r = SK.request.elem[i];
|
sv.r = r;
|
||||||
SaveUsingTable(filename, 'r');
|
SaveUsingTable(filename, 'r');
|
||||||
fprintf(fh, "AddRequest\n\n");
|
fprintf(fh, "AddRequest\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
for(auto &e : SK.entity) {
|
||||||
(SK.entity.elem[i]).CalculateNumerical(/*forExport=*/true);
|
e.CalculateNumerical(/*forExport=*/true);
|
||||||
sv.e = SK.entity.elem[i];
|
sv.e = e;
|
||||||
SaveUsingTable(filename, 'e');
|
SaveUsingTable(filename, 'e');
|
||||||
fprintf(fh, "AddEntity\n\n");
|
fprintf(fh, "AddEntity\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &c : SK.constraint) {
|
||||||
sv.c = SK.constraint.elem[i];
|
sv.c = c;
|
||||||
SaveUsingTable(filename, 'c');
|
SaveUsingTable(filename, 'c');
|
||||||
fprintf(fh, "AddConstraint\n\n");
|
fprintf(fh, "AddConstraint\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.style.n; i++) {
|
for(auto &s : SK.style) {
|
||||||
sv.s = SK.style.elem[i];
|
sv.s = s;
|
||||||
if(sv.s.h.v >= Style::FIRST_CUSTOM) {
|
if(sv.s.h.v >= Style::FIRST_CUSTOM) {
|
||||||
SaveUsingTable(filename, 's');
|
SaveUsingTable(filename, 's');
|
||||||
fprintf(fh, "AddStyle\n\n");
|
fprintf(fh, "AddStyle\n\n");
|
||||||
|
103
src/generate.cpp
103
src/generate.cpp
@ -14,10 +14,9 @@ void SolveSpaceUI::MarkGroupDirtyByEntity(hEntity he) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::MarkGroupDirty(hGroup hg, bool onlyThis) {
|
void SolveSpaceUI::MarkGroupDirty(hGroup hg, bool onlyThis) {
|
||||||
int i;
|
|
||||||
bool go = false;
|
bool go = false;
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
for(auto const &gh : SK.groupOrder) {
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
Group *g = SK.GetGroup(gh);
|
||||||
if(g->h == hg) {
|
if(g->h == hg) {
|
||||||
go = true;
|
go = true;
|
||||||
}
|
}
|
||||||
@ -31,23 +30,20 @@ void SolveSpaceUI::MarkGroupDirty(hGroup hg, bool onlyThis) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpaceUI::PruneOrphans() {
|
bool SolveSpaceUI::PruneOrphans() {
|
||||||
int i;
|
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
|
||||||
Request *r = &(SK.request.elem[i]);
|
|
||||||
if(GroupExists(r->group)) continue;
|
|
||||||
|
|
||||||
|
auto r = std::find_if(SK.request.begin(), SK.request.end(),
|
||||||
|
[&](Request &r) { return !GroupExists(r.group); });
|
||||||
|
if(r != SK.request.end()) {
|
||||||
(deleted.requests)++;
|
(deleted.requests)++;
|
||||||
SK.request.RemoveById(r->h);
|
SK.request.RemoveById(r->h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
auto c = std::find_if(SK.constraint.begin(), SK.constraint.end(),
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
[&](Constraint &c) { return !GroupExists(c.group); });
|
||||||
if(GroupExists(c->group)) continue;
|
if(c != SK.constraint.end()) {
|
||||||
|
|
||||||
(deleted.constraints)++;
|
(deleted.constraints)++;
|
||||||
(deleted.nonTrivialConstraints)++;
|
(deleted.nonTrivialConstraints)++;
|
||||||
|
|
||||||
SK.constraint.RemoveById(c->h);
|
SK.constraint.RemoveById(c->h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -91,44 +87,38 @@ bool SolveSpaceUI::PruneGroups(hGroup hg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpaceUI::PruneRequests(hGroup hg) {
|
bool SolveSpaceUI::PruneRequests(hGroup hg) {
|
||||||
int i;
|
auto e = std::find_if(SK.entity.begin(), SK.entity.end(),
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
[&](Entity &e) { return e.group == hg && !EntityExists(e.workplane); });
|
||||||
Entity *e = &(SK.entity.elem[i]);
|
if(e != SK.entity.end()) {
|
||||||
if(e->group != hg) continue;
|
|
||||||
|
|
||||||
if(EntityExists(e->workplane)) continue;
|
|
||||||
|
|
||||||
ssassert(e->h.isFromRequest(), "Only explicitly created entities can be pruned");
|
|
||||||
|
|
||||||
(deleted.requests)++;
|
(deleted.requests)++;
|
||||||
SK.request.RemoveById(e->h.request());
|
SK.entity.RemoveById(e->h);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpaceUI::PruneConstraints(hGroup hg) {
|
bool SolveSpaceUI::PruneConstraints(hGroup hg) {
|
||||||
int i;
|
auto c = std::find_if(SK.constraint.begin(), SK.constraint.end(), [&](Constraint &c) {
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
if(c.group != hg)
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
return false;
|
||||||
if(c->group != hg) continue;
|
|
||||||
|
|
||||||
if(EntityExists(c->workplane) &&
|
if(EntityExists(c.workplane) &&
|
||||||
EntityExists(c->ptA) &&
|
EntityExists(c.ptA) &&
|
||||||
EntityExists(c->ptB) &&
|
EntityExists(c.ptB) &&
|
||||||
EntityExists(c->entityA) &&
|
EntityExists(c.entityA) &&
|
||||||
EntityExists(c->entityB) &&
|
EntityExists(c.entityB) &&
|
||||||
EntityExists(c->entityC) &&
|
EntityExists(c.entityC) &&
|
||||||
EntityExists(c->entityD))
|
EntityExists(c.entityD)) {
|
||||||
{
|
return false;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(c != SK.constraint.end()) {
|
||||||
(deleted.constraints)++;
|
(deleted.constraints)++;
|
||||||
if(c->type != Constraint::Type::POINTS_COINCIDENT &&
|
if(c->type != Constraint::Type::POINTS_COINCIDENT &&
|
||||||
c->type != Constraint::Type::HORIZONTAL &&
|
c->type != Constraint::Type::HORIZONTAL &&
|
||||||
c->type != Constraint::Type::VERTICAL)
|
c->type != Constraint::Type::VERTICAL) {
|
||||||
{
|
|
||||||
(deleted.nonTrivialConstraints)++;
|
(deleted.nonTrivialConstraints)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,14 +129,13 @@ bool SolveSpaceUI::PruneConstraints(hGroup hg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox) {
|
void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox) {
|
||||||
int first = 0, last = 0, i, j;
|
int first = 0, last = 0, i;
|
||||||
|
|
||||||
uint64_t startMillis = GetMilliseconds(),
|
uint64_t startMillis = GetMilliseconds(),
|
||||||
endMillis;
|
endMillis;
|
||||||
|
|
||||||
SK.groupOrder.Clear();
|
SK.groupOrder.Clear();
|
||||||
for(int i = 0; i < SK.group.n; i++)
|
for(auto &g : SK.group) { SK.groupOrder.Add(&g.h); }
|
||||||
SK.groupOrder.Add(&SK.group.elem[i].h);
|
|
||||||
std::sort(SK.groupOrder.begin(), SK.groupOrder.end(),
|
std::sort(SK.groupOrder.begin(), SK.groupOrder.end(),
|
||||||
[](const hGroup &ha, const hGroup &hb) {
|
[](const hGroup &ha, const hGroup &hb) {
|
||||||
return SK.GetGroup(ha)->order < SK.GetGroup(hb)->order;
|
return SK.GetGroup(ha)->order < SK.GetGroup(hb)->order;
|
||||||
@ -233,14 +222,14 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
|||||||
if(PruneGroups(g->h))
|
if(PruneGroups(g->h))
|
||||||
goto pruned;
|
goto pruned;
|
||||||
|
|
||||||
for(j = 0; j < SK.request.n; j++) {
|
for(auto &req : SK.request) {
|
||||||
Request *r = &(SK.request.elem[j]);
|
Request *r = &req;
|
||||||
if(r->group != g->h) continue;
|
if(r->group != g->h) continue;
|
||||||
|
|
||||||
r->Generate(&(SK.entity), &(SK.param));
|
r->Generate(&(SK.entity), &(SK.param));
|
||||||
}
|
}
|
||||||
for(j = 0; j < SK.constraint.n; j++) {
|
for(auto &con : SK.constraint) {
|
||||||
Constraint *c = &SK.constraint.elem[j];
|
Constraint *c = &con;
|
||||||
if(c->group != g->h) continue;
|
if(c->group != g->h) continue;
|
||||||
|
|
||||||
c->Generate(&(SK.param));
|
c->Generate(&(SK.param));
|
||||||
@ -254,8 +243,8 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
|||||||
|
|
||||||
// Use the previous values for params that we've seen before, as
|
// Use the previous values for params that we've seen before, as
|
||||||
// initial guesses for the solver.
|
// initial guesses for the solver.
|
||||||
for(j = 0; j < SK.param.n; j++) {
|
for(auto &p : SK.param) {
|
||||||
Param *newp = &(SK.param.elem[j]);
|
Param *newp = &p;
|
||||||
if(newp->known) continue;
|
if(newp->known) continue;
|
||||||
|
|
||||||
Param *prevp = prev.FindByIdNoOops(newp->h);
|
Param *prevp = prev.FindByIdNoOops(newp->h);
|
||||||
@ -270,6 +259,7 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
|||||||
g->solved.how = SolveResult::OKAY;
|
g->solved.how = SolveResult::OKAY;
|
||||||
g->clean = true;
|
g->clean = true;
|
||||||
} else {
|
} else {
|
||||||
|
// this i is an index in groupOrder
|
||||||
if(i >= first && i <= last) {
|
if(i >= first && i <= last) {
|
||||||
// The group falls inside the range, so really solve it,
|
// The group falls inside the range, so really solve it,
|
||||||
// and then regenerate the mesh based on the solved stuff.
|
// and then regenerate the mesh based on the solved stuff.
|
||||||
@ -284,8 +274,8 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
|||||||
// The group falls outside the range, so just assume that
|
// The group falls outside the range, so just assume that
|
||||||
// it's good wherever we left it. The mesh is unchanged,
|
// it's good wherever we left it. The mesh is unchanged,
|
||||||
// and the parameters must be marked as known.
|
// and the parameters must be marked as known.
|
||||||
for(j = 0; j < SK.param.n; j++) {
|
for(auto &p : SK.param) {
|
||||||
Param *newp = &(SK.param.elem[j]);
|
Param *newp = &p;
|
||||||
|
|
||||||
Param *prevp = prev.FindByIdNoOops(newp->h);
|
Param *prevp = prev.FindByIdNoOops(newp->h);
|
||||||
if(prevp) newp->known = true;
|
if(prevp) newp->known = true;
|
||||||
@ -295,8 +285,8 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And update any reference dimensions with their new values
|
// And update any reference dimensions with their new values
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &con : SK.constraint) {
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
Constraint *c = &con;
|
||||||
if(c->reference) {
|
if(c->reference) {
|
||||||
c->ModifyToSatisfy();
|
c->ModifyToSatisfy();
|
||||||
}
|
}
|
||||||
@ -505,20 +495,19 @@ void SolveSpaceUI::SolveGroupAndReport(hGroup hg, bool andFindFree) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::WriteEqSystemForGroup(hGroup hg) {
|
void SolveSpaceUI::WriteEqSystemForGroup(hGroup hg) {
|
||||||
int i;
|
|
||||||
// Clear out the system to be solved.
|
// Clear out the system to be solved.
|
||||||
sys.entity.Clear();
|
sys.entity.Clear();
|
||||||
sys.param.Clear();
|
sys.param.Clear();
|
||||||
sys.eq.Clear();
|
sys.eq.Clear();
|
||||||
// And generate all the params for requests in this group
|
// And generate all the params for requests in this group
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
for(auto &req : SK.request) {
|
||||||
Request *r = &(SK.request.elem[i]);
|
Request *r = &req;
|
||||||
if(r->group != hg) continue;
|
if(r->group != hg) continue;
|
||||||
|
|
||||||
r->Generate(&(sys.entity), &(sys.param));
|
r->Generate(&(sys.entity), &(sys.param));
|
||||||
}
|
}
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &con : SK.constraint) {
|
||||||
Constraint *c = &SK.constraint.elem[i];
|
Constraint *c = &con;
|
||||||
if(c->group != hg) continue;
|
if(c->group != hg) continue;
|
||||||
|
|
||||||
c->Generate(&(sys.param));
|
c->Generate(&(sys.param));
|
||||||
@ -527,8 +516,8 @@ void SolveSpaceUI::WriteEqSystemForGroup(hGroup hg) {
|
|||||||
Group *g = SK.GetGroup(hg);
|
Group *g = SK.GetGroup(hg);
|
||||||
g->Generate(&(sys.entity), &(sys.param));
|
g->Generate(&(sys.entity), &(sys.param));
|
||||||
// Set the initial guesses for all the params
|
// Set the initial guesses for all the params
|
||||||
for(i = 0; i < sys.param.n; i++) {
|
for(auto ¶m : sys.param) {
|
||||||
Param *p = &(sys.param.elem[i]);
|
Param *p = ¶m;
|
||||||
p->known = false;
|
p->known = false;
|
||||||
p->val = SK.GetParam(p->h)->val;
|
p->val = SK.GetParam(p->h)->val;
|
||||||
}
|
}
|
||||||
|
@ -381,7 +381,9 @@ void GraphicsWindow::Init() {
|
|||||||
orig.projUp = projUp;
|
orig.projUp = projUp;
|
||||||
|
|
||||||
// And with the last group active
|
// And with the last group active
|
||||||
activeGroup = SK.groupOrder.elem[SK.groupOrder.n - 1];
|
ssassert(!SK.groupOrder.IsEmpty(),
|
||||||
|
"Group order can't be empty since we will activate the last group.");
|
||||||
|
activeGroup = SK.groupOrder[SK.groupOrder.n - 1];
|
||||||
SK.GetGroup(activeGroup)->Activate();
|
SK.GetGroup(activeGroup)->Activate();
|
||||||
|
|
||||||
showWorkplanes = false;
|
showWorkplanes = false;
|
||||||
|
@ -308,8 +308,8 @@ void Group::MenuGroup(Command id, Platform::Path linkFile) {
|
|||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
bool afterActive = false;
|
bool afterActive = false;
|
||||||
for(int i = 0; i < SK.groupOrder.n; i++) {
|
for(hGroup hg : SK.groupOrder) {
|
||||||
Group *gi = SK.GetGroup(SK.groupOrder.elem[i]);
|
Group *gi = SK.GetGroup(hg);
|
||||||
if(afterActive)
|
if(afterActive)
|
||||||
gi->order += 1;
|
gi->order += 1;
|
||||||
if(gi->h == SS.GW.activeGroup) {
|
if(gi->h == SS.GW.activeGroup) {
|
||||||
@ -472,6 +472,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
// Get some arbitrary point in the sketch, that will be used
|
// Get some arbitrary point in the sketch, that will be used
|
||||||
// as a reference when defining top and bottom faces.
|
// as a reference when defining top and bottom faces.
|
||||||
hEntity pt = { 0 };
|
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++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
@ -505,6 +506,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
// Remapped entity index.
|
// Remapped entity index.
|
||||||
int ai = 1;
|
int ai = 1;
|
||||||
|
|
||||||
|
// 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->elem[i]);
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
@ -656,6 +658,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.
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
@ -691,6 +694,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.
|
||||||
for(i = 0; i < entity->n; i++) {
|
for(i = 0; i < entity->n; i++) {
|
||||||
Entity *e = &(entity->elem[i]);
|
Entity *e = &(entity->elem[i]);
|
||||||
if(e->group != opA) continue;
|
if(e->group != opA) continue;
|
||||||
@ -717,6 +721,7 @@ void Group::Generate(IdList<Entity,hEntity> *entity,
|
|||||||
AddParam(param, h.param(5), 0);
|
AddParam(param, h.param(5), 0);
|
||||||
AddParam(param, h.param(6), 0);
|
AddParam(param, h.param(6), 0);
|
||||||
|
|
||||||
|
// 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.elem[i]);
|
||||||
CopyEntity(entity, ie, 0, 0,
|
CopyEntity(entity, ie, 0, 0,
|
||||||
|
@ -14,13 +14,15 @@ void Group::AssembleLoops(bool *allClosed,
|
|||||||
SBezierList sbl = {};
|
SBezierList sbl = {};
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
for(auto &e : SK.entity) {
|
||||||
Entity *e = &(SK.entity.elem[i]);
|
if(e.group != h)
|
||||||
if(e->group != h) continue;
|
continue;
|
||||||
if(e->construction) continue;
|
if(e.construction)
|
||||||
if(e->forceHidden) continue;
|
continue;
|
||||||
|
if(e.forceHidden)
|
||||||
|
continue;
|
||||||
|
|
||||||
e->GenerateBezierCurves(&sbl);
|
e.GenerateBezierCurves(&sbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
SBezier *sb;
|
SBezier *sb;
|
||||||
@ -235,6 +237,8 @@ void Group::GenerateShellAndMesh() {
|
|||||||
// that face, so that the user can select them with the mouse.
|
// that face, so that the user can select them with the mouse.
|
||||||
Vector onOrig = sbls->point;
|
Vector onOrig = sbls->point;
|
||||||
int i;
|
int i;
|
||||||
|
// 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++) {
|
for(i = is; i < thisShell.surface.n; i++) {
|
||||||
SSurface *ss = &(thisShell.surface.elem[i]);
|
SSurface *ss = &(thisShell.surface.elem[i]);
|
||||||
hEntity face = Entity::NO_ENTITY;
|
hEntity face = Entity::NO_ENTITY;
|
||||||
@ -490,13 +494,15 @@ void Group::GenerateDisplayItems() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Group *Group::PreviousGroup() const {
|
Group *Group::PreviousGroup() const {
|
||||||
int i;
|
Group *prev = nullptr;
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
for(auto const &gh : SK.groupOrder) {
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
Group *g = SK.GetGroup(gh);
|
||||||
if(g->h == h) break;
|
if(g->h == h) {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
prev = g;
|
||||||
}
|
}
|
||||||
if(i == 0 || i >= SK.groupOrder.n) return NULL;
|
return nullptr;
|
||||||
return SK.GetGroup(SK.groupOrder.elem[i - 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Group *Group::RunningMeshGroup() const {
|
Group *Group::RunningMeshGroup() const {
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
// Useful when splitting, tangent arcing, or removing bezier points.
|
// Useful when splitting, tangent arcing, or removing bezier points.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
||||||
int i;
|
for(auto &c : SK.constraint) {
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
if(c.ptA == oldpt)
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
c.ptA = newpt;
|
||||||
if(c->ptA == oldpt) c->ptA = newpt;
|
if(c.ptB == oldpt)
|
||||||
if(c->ptB == oldpt) c->ptB = newpt;
|
c.ptB = newpt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,14 +25,13 @@ void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GraphicsWindow::RemoveConstraintsForPointBeingDeleted(hEntity hpt) {
|
void GraphicsWindow::RemoveConstraintsForPointBeingDeleted(hEntity hpt) {
|
||||||
SK.constraint.ClearTags();
|
SK.constraint.ClearTags();
|
||||||
for(int i = 0; i < SK.constraint.n; i++) {
|
for(auto &c : SK.constraint) {
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
if(c.ptA == hpt || c.ptB == hpt) {
|
||||||
if(c->ptA == hpt || c->ptB == hpt) {
|
c.tag = 1;
|
||||||
c->tag = 1;
|
|
||||||
(SS.deleted.constraints)++;
|
(SS.deleted.constraints)++;
|
||||||
if(c->type != Constraint::Type::POINTS_COINCIDENT &&
|
if(c.type != Constraint::Type::POINTS_COINCIDENT &&
|
||||||
c->type != Constraint::Type::HORIZONTAL &&
|
c.type != Constraint::Type::HORIZONTAL &&
|
||||||
c->type != Constraint::Type::VERTICAL)
|
c.type != Constraint::Type::VERTICAL)
|
||||||
{
|
{
|
||||||
(SS.deleted.nonTrivialConstraints)++;
|
(SS.deleted.nonTrivialConstraints)++;
|
||||||
}
|
}
|
||||||
@ -270,18 +269,18 @@ void GraphicsWindow::MakeTangentArc() {
|
|||||||
hRequest hreq[2];
|
hRequest hreq[2];
|
||||||
hEntity hent[2];
|
hEntity hent[2];
|
||||||
bool pointf[2];
|
bool pointf[2];
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
for(auto &r : SK.request) {
|
||||||
Request *r = &(SK.request.elem[i]);
|
if(r.group != activeGroup)
|
||||||
if(r->group != activeGroup) continue;
|
continue;
|
||||||
if(r->workplane != ActiveWorkplane()) continue;
|
if(r.workplane != ActiveWorkplane())
|
||||||
if(r->construction) continue;
|
continue;
|
||||||
if(r->type != Request::Type::LINE_SEGMENT &&
|
if(r.construction)
|
||||||
r->type != Request::Type::ARC_OF_CIRCLE)
|
continue;
|
||||||
{
|
if(r.type != Request::Type::LINE_SEGMENT && r.type != Request::Type::ARC_OF_CIRCLE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity *e = SK.GetEntity(r->h.entity(0));
|
Entity *e = SK.GetEntity(r.h.entity(0));
|
||||||
Vector ps = e->EndpointStart(),
|
Vector ps = e->EndpointStart(),
|
||||||
pf = e->EndpointFinish();
|
pf = e->EndpointFinish();
|
||||||
|
|
||||||
@ -292,8 +291,8 @@ void GraphicsWindow::MakeTangentArc() {
|
|||||||
// finish of this entity.
|
// finish of this entity.
|
||||||
ent[c] = e;
|
ent[c] = e;
|
||||||
hent[c] = e->h;
|
hent[c] = e->h;
|
||||||
req[c] = r;
|
req[c] = &r;
|
||||||
hreq[c] = r->h;
|
hreq[c] = r.h;
|
||||||
pointf[c] = (pf.Equals(pshared));
|
pointf[c] = (pf.Equals(pshared));
|
||||||
}
|
}
|
||||||
c++;
|
c++;
|
||||||
@ -603,15 +602,16 @@ hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
|
|||||||
// Finally, delete the request that generated the original entity.
|
// Finally, delete the request that generated the original entity.
|
||||||
Request::Type reqType = EntReqTable::GetRequestForEntity(entityType);
|
Request::Type reqType = EntReqTable::GetRequestForEntity(entityType);
|
||||||
SK.request.ClearTags();
|
SK.request.ClearTags();
|
||||||
for(int i = 0; i < SK.request.n; i++) {
|
for(auto &r : SK.request) {
|
||||||
Request *r = &(SK.request.elem[i]);
|
if(r.group != activeGroup)
|
||||||
if(r->group != activeGroup) continue;
|
continue;
|
||||||
if(r->type != reqType) continue;
|
if(r.type != reqType)
|
||||||
|
continue;
|
||||||
|
|
||||||
// If the user wants to keep the old entities around, they can just
|
// If the user wants to keep the old entities around, they can just
|
||||||
// mark them construction first.
|
// mark them construction first.
|
||||||
if(he == r->h.entity(0) && !r->construction) {
|
if(he == r.h.entity(0) && !r.construction) {
|
||||||
r->tag = 1;
|
r.tag = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,16 +508,16 @@ void SEdgeList::MergeCollinearSegments(Vector a, Vector b) {
|
|||||||
qsort(l.elem, l.n, sizeof(l.elem[0]), ByTAlongLine);
|
qsort(l.elem, l.n, sizeof(l.elem[0]), ByTAlongLine);
|
||||||
|
|
||||||
l.ClearTags();
|
l.ClearTags();
|
||||||
int i;
|
SEdge *prev = nullptr;
|
||||||
for(i = 1; i < l.n; i++) {
|
for(auto &now : l) {
|
||||||
SEdge *prev = &(l.elem[i-1]),
|
if(prev != nullptr) {
|
||||||
*now = &(l.elem[i]);
|
if((prev->b).Equals(now.a) && prev->auxA == now.auxA) {
|
||||||
|
// The previous segment joins up to us; so merge it into us.
|
||||||
if((prev->b).Equals(now->a) && prev->auxA == now->auxA) {
|
prev->tag = 1;
|
||||||
// The previous segment joins up to us; so merge it into us.
|
now.a = prev->a;
|
||||||
prev->tag = 1;
|
}
|
||||||
now->a = prev->a;
|
|
||||||
}
|
}
|
||||||
|
prev = &now;
|
||||||
}
|
}
|
||||||
l.RemoveTagged();
|
l.RemoveTagged();
|
||||||
}
|
}
|
||||||
|
100
src/system.cpp
100
src/system.cpp
@ -20,28 +20,29 @@ const double System::RANK_MAG_TOLERANCE = 1e-4;
|
|||||||
const double System::CONVERGE_TOLERANCE = (LENGTH_EPS/(1e2));
|
const double System::CONVERGE_TOLERANCE = (LENGTH_EPS/(1e2));
|
||||||
|
|
||||||
bool System::WriteJacobian(int tag) {
|
bool System::WriteJacobian(int tag) {
|
||||||
int a, i, j;
|
|
||||||
|
|
||||||
j = 0;
|
int j = 0;
|
||||||
for(a = 0; a < param.n; a++) {
|
for(auto &p : param) {
|
||||||
if(j >= MAX_UNKNOWNS) return false;
|
if(j >= MAX_UNKNOWNS)
|
||||||
|
return false;
|
||||||
|
|
||||||
Param *p = &(param.elem[a]);
|
if(p.tag != tag)
|
||||||
if(p->tag != tag) continue;
|
continue;
|
||||||
mat.param[j] = p->h;
|
mat.param[j] = p.h;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
mat.n = j;
|
mat.n = j;
|
||||||
|
|
||||||
i = 0;
|
int i = 0;
|
||||||
for(a = 0; a < eq.n; a++) {
|
|
||||||
|
for(auto &e : eq) {
|
||||||
if(i >= MAX_UNKNOWNS) return false;
|
if(i >= MAX_UNKNOWNS) return false;
|
||||||
|
|
||||||
Equation *e = &(eq.elem[a]);
|
if(e.tag != tag)
|
||||||
if(e->tag != tag) continue;
|
continue;
|
||||||
|
|
||||||
mat.eq[i] = e->h;
|
mat.eq[i] = e.h;
|
||||||
Expr *f = e->e->DeepCopyWithParamsAsPointers(¶m, &(SK.param));
|
Expr *f = e.e->DeepCopyWithParamsAsPointers(¶m, &(SK.param));
|
||||||
f = f->FoldConstants();
|
f = f->FoldConstants();
|
||||||
|
|
||||||
// Hash table (61 bits) to accelerate generation of zero partials.
|
// Hash table (61 bits) to accelerate generation of zero partials.
|
||||||
@ -85,10 +86,8 @@ bool System::IsDragged(hParam p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void System::SolveBySubstitution() {
|
void System::SolveBySubstitution() {
|
||||||
int i;
|
for(auto &teq : eq) {
|
||||||
for(i = 0; i < eq.n; i++) {
|
Expr *tex = teq.e;
|
||||||
Equation *teq = &(eq.elem[i]);
|
|
||||||
Expr *tex = teq->e;
|
|
||||||
|
|
||||||
if(tex->op == Expr::Op::MINUS &&
|
if(tex->op == Expr::Op::MINUS &&
|
||||||
tex->a->op == Expr::Op::PARAM &&
|
tex->a->op == Expr::Op::PARAM &&
|
||||||
@ -108,22 +107,19 @@ void System::SolveBySubstitution() {
|
|||||||
std::swap(a, b);
|
std::swap(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
int j;
|
for(auto &req : eq) {
|
||||||
for(j = 0; j < eq.n; j++) {
|
req.e->Substitute(a, b); // A becomes B, B unchanged
|
||||||
Equation *req = &(eq.elem[j]);
|
|
||||||
(req->e)->Substitute(a, b); // A becomes B, B unchanged
|
|
||||||
}
|
}
|
||||||
for(j = 0; j < param.n; j++) {
|
for(auto &rp : param) {
|
||||||
Param *rp = &(param.elem[j]);
|
if(rp.substd == a) {
|
||||||
if(rp->substd == a) {
|
rp.substd = b;
|
||||||
rp->substd = b;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Param *ptr = param.FindById(a);
|
Param *ptr = param.FindById(a);
|
||||||
ptr->tag = VAR_SUBSTITUTED;
|
ptr->tag = VAR_SUBSTITUTED;
|
||||||
ptr->substd = b;
|
ptr->substd = b;
|
||||||
|
|
||||||
teq->tag = EQ_SUBSTITUTED;
|
teq.tag = EQ_SUBSTITUTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,10 +320,9 @@ bool System::NewtonSolve(int tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
|
void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
|
||||||
int i;
|
|
||||||
// Generate all the equations from constraints in this group
|
// Generate all the equations from constraints in this group
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &con : SK.constraint) {
|
||||||
ConstraintBase *c = &(SK.constraint.elem[i]);
|
ConstraintBase *c = &con;
|
||||||
if(c->group != g->h) continue;
|
if(c->group != g->h) continue;
|
||||||
if(c->h == hc) continue;
|
if(c->h == hc) continue;
|
||||||
|
|
||||||
@ -349,8 +344,8 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
|
|||||||
c->GenerateEquations(&eq);
|
c->GenerateEquations(&eq);
|
||||||
}
|
}
|
||||||
// And the equations from entities
|
// And the equations from entities
|
||||||
for(i = 0; i < SK.entity.n; i++) {
|
for(auto &ent : SK.entity) {
|
||||||
EntityBase *e = &(SK.entity.elem[i]);
|
EntityBase *e = &ent;
|
||||||
if(e->group != g->h) continue;
|
if(e->group != g->h) continue;
|
||||||
|
|
||||||
e->GenerateEquations(&eq);
|
e->GenerateEquations(&eq);
|
||||||
@ -360,11 +355,11 @@ void System::WriteEquationsExceptFor(hConstraint hc, Group *g) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad, bool forceDofCheck) {
|
void System::FindWhichToRemoveToFixJacobian(Group *g, List<hConstraint> *bad, bool forceDofCheck) {
|
||||||
int a, i;
|
int a;
|
||||||
|
|
||||||
for(a = 0; a < 2; a++) {
|
for(a = 0; a < 2; a++) {
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &con : SK.constraint) {
|
||||||
ConstraintBase *c = &(SK.constraint.elem[i]);
|
ConstraintBase *c = &con;
|
||||||
if(c->group != g->h) continue;
|
if(c->group != g->h) continue;
|
||||||
if((c->type == Constraint::Type::POINTS_COINCIDENT && a == 0) ||
|
if((c->type == Constraint::Type::POINTS_COINCIDENT && a == 0) ||
|
||||||
(c->type != Constraint::Type::POINTS_COINCIDENT && a == 1))
|
(c->type != Constraint::Type::POINTS_COINCIDENT && a == 1))
|
||||||
@ -431,18 +426,18 @@ SolveResult System::Solve(Group *g, int *rank, int *dof, List<hConstraint> *bad,
|
|||||||
// the system is consistent yet, but if it isn't then we'll catch that
|
// the system is consistent yet, but if it isn't then we'll catch that
|
||||||
// later.
|
// later.
|
||||||
int alone = 1;
|
int alone = 1;
|
||||||
for(i = 0; i < eq.n; i++) {
|
for(auto &e : eq) {
|
||||||
Equation *e = &(eq.elem[i]);
|
if(e.tag != 0)
|
||||||
if(e->tag != 0) continue;
|
continue;
|
||||||
|
|
||||||
hParam hp = e->e->ReferencedParams(¶m);
|
hParam hp = e.e->ReferencedParams(¶m);
|
||||||
if(hp == Expr::NO_PARAMS) continue;
|
if(hp == Expr::NO_PARAMS) continue;
|
||||||
if(hp == Expr::MULTIPLE_PARAMS) continue;
|
if(hp == Expr::MULTIPLE_PARAMS) continue;
|
||||||
|
|
||||||
Param *p = param.FindById(hp);
|
Param *p = param.FindById(hp);
|
||||||
if(p->tag != 0) continue; // let rank test catch inconsistency
|
if(p->tag != 0) continue; // let rank test catch inconsistency
|
||||||
|
|
||||||
e->tag = alone;
|
e.tag = alone;
|
||||||
p->tag = alone;
|
p->tag = alone;
|
||||||
WriteJacobian(alone);
|
WriteJacobian(alone);
|
||||||
if(!NewtonSolve(alone)) {
|
if(!NewtonSolve(alone)) {
|
||||||
@ -480,23 +475,23 @@ SolveResult System::Solve(Group *g, int *rank, int *dof, List<hConstraint> *bad,
|
|||||||
}
|
}
|
||||||
// System solved correctly, so write the new values back in to the
|
// System solved correctly, so write the new values back in to the
|
||||||
// main parameter table.
|
// main parameter table.
|
||||||
for(i = 0; i < param.n; i++) {
|
for(auto &p : param) {
|
||||||
Param *p = &(param.elem[i]);
|
|
||||||
double val;
|
double val;
|
||||||
if(p->tag == VAR_SUBSTITUTED) {
|
if(p.tag == VAR_SUBSTITUTED) {
|
||||||
val = param.FindById(p->substd)->val;
|
val = param.FindById(p.substd)->val;
|
||||||
} else {
|
} else {
|
||||||
val = p->val;
|
val = p.val;
|
||||||
}
|
}
|
||||||
Param *pp = SK.GetParam(p->h);
|
Param *pp = SK.GetParam(p.h);
|
||||||
pp->val = val;
|
pp->val = val;
|
||||||
pp->known = true;
|
pp->known = true;
|
||||||
pp->free = p->free;
|
pp->free = p.free;
|
||||||
}
|
}
|
||||||
return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY;
|
return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY;
|
||||||
|
|
||||||
didnt_converge:
|
didnt_converge:
|
||||||
SK.constraint.ClearTags();
|
SK.constraint.ClearTags();
|
||||||
|
// Not using range-for here because index is used in additional ways
|
||||||
for(i = 0; i < eq.n; i++) {
|
for(i = 0; i < eq.n; i++) {
|
||||||
if(ffabs(mat.B.num[i]) > CONVERGE_TOLERANCE || isnan(mat.B.num[i])) {
|
if(ffabs(mat.B.num[i]) > CONVERGE_TOLERANCE || isnan(mat.B.num[i])) {
|
||||||
// This constraint is unsatisfied.
|
// This constraint is unsatisfied.
|
||||||
@ -553,20 +548,19 @@ void System::MarkParamsFree(bool find) {
|
|||||||
// If requested, find all the free (unbound) variables. This might be
|
// If requested, find all the free (unbound) variables. This might be
|
||||||
// more than the number of degrees of freedom. Don't always do this,
|
// more than the number of degrees of freedom. Don't always do this,
|
||||||
// because the display would get annoying and it's slow.
|
// because the display would get annoying and it's slow.
|
||||||
for(int i = 0; i < param.n; i++) {
|
for(auto &p : param) {
|
||||||
Param *p = &(param.elem[i]);
|
p.free = false;
|
||||||
p->free = false;
|
|
||||||
|
|
||||||
if(find) {
|
if(find) {
|
||||||
if(p->tag == 0) {
|
if(p.tag == 0) {
|
||||||
p->tag = VAR_DOF_TEST;
|
p.tag = VAR_DOF_TEST;
|
||||||
WriteJacobian(0);
|
WriteJacobian(0);
|
||||||
EvalJacobian();
|
EvalJacobian();
|
||||||
int rank = CalculateRank();
|
int rank = CalculateRank();
|
||||||
if(rank == mat.m) {
|
if(rank == mat.m) {
|
||||||
p->free = true;
|
p.free = true;
|
||||||
}
|
}
|
||||||
p->tag = 0;
|
p.tag = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,9 @@ void TextWindow::ScreenToggleGroupShown(int link, uint32_t v) {
|
|||||||
}
|
}
|
||||||
void TextWindow::ScreenShowGroupsSpecial(int link, uint32_t v) {
|
void TextWindow::ScreenShowGroupsSpecial(int link, uint32_t v) {
|
||||||
bool state = link == 's';
|
bool state = link == 's';
|
||||||
for(int i = 0; i < SK.groupOrder.n; i++) {
|
for(hGroup hg : SK.groupOrder) {
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
Group *g = SK.GetGroup(hg);
|
||||||
|
|
||||||
g->visible = state;
|
g->visible = state;
|
||||||
}
|
}
|
||||||
SS.GW.persistentDirty = true;
|
SS.GW.persistentDirty = true;
|
||||||
@ -98,10 +99,11 @@ void TextWindow::ShowListOfGroups() {
|
|||||||
|
|
||||||
Printf(true, "%Ft active");
|
Printf(true, "%Ft active");
|
||||||
Printf(false, "%Ft shown dof group-name%E");
|
Printf(false, "%Ft shown dof group-name%E");
|
||||||
int i;
|
|
||||||
bool afterActive = false;
|
bool afterActive = false;
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
bool backgroundParity = false;
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
for(hGroup hg : SK.groupOrder) {
|
||||||
|
Group *g = SK.GetGroup(hg);
|
||||||
|
|
||||||
std::string s = g->DescriptionString();
|
std::string s = g->DescriptionString();
|
||||||
bool active = (g->h == SS.GW.activeGroup);
|
bool active = (g->h == SS.GW.activeGroup);
|
||||||
bool shown = g->visible;
|
bool shown = g->visible;
|
||||||
@ -121,30 +123,32 @@ void TextWindow::ShowListOfGroups() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool ref = (g->h == Group::HGROUP_REFERENCES);
|
bool ref = (g->h == Group::HGROUP_REFERENCES);
|
||||||
Printf(false, "%Bp%Fd "
|
Printf(false,
|
||||||
|
"%Bp%Fd "
|
||||||
"%Ft%s%Fb%D%f%Ll%s%E "
|
"%Ft%s%Fb%D%f%Ll%s%E "
|
||||||
"%Fb%s%D%f%Ll%s%E "
|
"%Fb%s%D%f%Ll%s%E "
|
||||||
"%Fp%D%f%s%Ll%s%E "
|
"%Fp%D%f%s%Ll%s%E "
|
||||||
"%Fl%Ll%D%f%s",
|
"%Fl%Ll%D%f%s",
|
||||||
// Alternate between light and dark backgrounds, for readability
|
// Alternate between light and dark backgrounds, for readability
|
||||||
(i & 1) ? 'd' : 'a',
|
backgroundParity ? 'd' : 'a',
|
||||||
// Link that activates the group
|
// Link that activates the group
|
||||||
ref ? " " : "",
|
ref ? " " : "",
|
||||||
g->h.v, (&TextWindow::ScreenActivateGroup),
|
g->h.v, (&TextWindow::ScreenActivateGroup),
|
||||||
ref ? "" : (active ? radioTrue : radioFalse),
|
ref ? "" : (active ? radioTrue : radioFalse),
|
||||||
// Link that hides or shows the group
|
// Link that hides or shows the group
|
||||||
afterActive ? " - " : "",
|
afterActive ? " - " : "",
|
||||||
g->h.v, (&TextWindow::ScreenToggleGroupShown),
|
g->h.v, (&TextWindow::ScreenToggleGroupShown),
|
||||||
afterActive ? "" : (shown ? checkTrue : checkFalse),
|
afterActive ? "" : (shown ? checkTrue : checkFalse),
|
||||||
// Link to the errors, if a problem occurred while solving
|
// Link to the errors, if a problem occurred while solving
|
||||||
ok ? (warn ? 'm' : (dof > 0 ? 'i' : 's')) : 'x',
|
ok ? (warn ? 'm' : (dof > 0 ? 'i' : 's')) : 'x',
|
||||||
g->h.v, (&TextWindow::ScreenHowGroupSolved),
|
g->h.v, (&TextWindow::ScreenHowGroupSolved),
|
||||||
ok ? (warn ? "err" : sdof) : "",
|
ok ? (warn ? "err" : sdof) : "",
|
||||||
ok ? "" : "ERR",
|
ok ? "" : "ERR",
|
||||||
// Link to a screen that gives more details on the group
|
// Link to a screen that gives more details on the group
|
||||||
g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str());
|
g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str());
|
||||||
|
|
||||||
if(active) afterActive = true;
|
if(active) afterActive = true;
|
||||||
|
backgroundParity = !backgroundParity;
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(true, " %Fl%Ls%fshow all%E / %Fl%Lh%fhide all%E",
|
Printf(true, " %Fl%Ls%fshow all%E / %Fl%Lh%fhide all%E",
|
||||||
@ -445,16 +449,17 @@ list_items:
|
|||||||
Printf(false, "");
|
Printf(false, "");
|
||||||
Printf(false, "%Ft requests in group");
|
Printf(false, "%Ft requests in group");
|
||||||
|
|
||||||
int i, a = 0;
|
int a = 0;
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
for(auto &r : SK.request) {
|
||||||
Request *r = &(SK.request.elem[i]);
|
|
||||||
|
|
||||||
if(r->group == shown.group) {
|
if(r.group == shown.group) {
|
||||||
std::string s = r->DescriptionString();
|
std::string s = r.DescriptionString();
|
||||||
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E",
|
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E",
|
||||||
(a & 1) ? 'd' : 'a',
|
(a & 1) ? 'd' : 'a',
|
||||||
r->h.v, (&TextWindow::ScreenSelectRequest),
|
r.h.v,
|
||||||
&(TextWindow::ScreenHoverRequest), s.c_str());
|
(&TextWindow::ScreenSelectRequest),
|
||||||
|
&(TextWindow::ScreenHoverRequest),
|
||||||
|
s.c_str());
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,16 +468,17 @@ list_items:
|
|||||||
a = 0;
|
a = 0;
|
||||||
Printf(false, "");
|
Printf(false, "");
|
||||||
Printf(false, "%Ft constraints in group (%d DOF)", g->solved.dof);
|
Printf(false, "%Ft constraints in group (%d DOF)", g->solved.dof);
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &c : SK.constraint) {
|
||||||
Constraint *c = &(SK.constraint.elem[i]);
|
|
||||||
|
|
||||||
if(c->group == shown.group) {
|
if(c.group == shown.group) {
|
||||||
std::string s = c->DescriptionString();
|
std::string s = c.DescriptionString();
|
||||||
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E %s",
|
Printf(false, "%Bp %Fl%Ll%D%f%h%s%E %s",
|
||||||
(a & 1) ? 'd' : 'a',
|
(a & 1) ? 'd' : 'a',
|
||||||
c->h.v, (&TextWindow::ScreenSelectConstraint),
|
c.h.v,
|
||||||
(&TextWindow::ScreenHoverConstraint), s.c_str(),
|
(&TextWindow::ScreenSelectConstraint),
|
||||||
c->reference ? "(ref)" : "");
|
(&TextWindow::ScreenHoverConstraint),
|
||||||
|
s.c_str(),
|
||||||
|
c.reference ? "(ref)" : "");
|
||||||
a++;
|
a++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,6 @@ void SolveSpaceUI::UndoEnableMenus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
||||||
int i;
|
|
||||||
|
|
||||||
if(uk->cnt == MAX_UNDO) {
|
if(uk->cnt == MAX_UNDO) {
|
||||||
UndoClearState(&(uk->d[uk->write]));
|
UndoClearState(&(uk->d[uk->write]));
|
||||||
// And then write in to this one again
|
// And then write in to this one again
|
||||||
@ -48,9 +46,9 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
|||||||
UndoState *ut = &(uk->d[uk->write]);
|
UndoState *ut = &(uk->d[uk->write]);
|
||||||
*ut = {};
|
*ut = {};
|
||||||
ut->group.ReserveMore(SK.group.n);
|
ut->group.ReserveMore(SK.group.n);
|
||||||
for(i = 0; i < SK.group.n; i++) {
|
for(Group &src : SK.group) {
|
||||||
Group *src = &(SK.group.elem[i]);
|
// Shallow copy
|
||||||
Group dest = *src;
|
Group dest(src);
|
||||||
// And then clean up all the stuff that needs to be a deep copy,
|
// And then clean up all the stuff that needs to be a deep copy,
|
||||||
// and zero out all the dynamic stuff that will get regenerated.
|
// and zero out all the dynamic stuff that will get regenerated.
|
||||||
dest.clean = false;
|
dest.clean = false;
|
||||||
@ -66,42 +64,32 @@ void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) {
|
|||||||
dest.displayMesh = {};
|
dest.displayMesh = {};
|
||||||
dest.displayOutlines = {};
|
dest.displayOutlines = {};
|
||||||
|
|
||||||
dest.remap = src->remap;
|
dest.remap = src.remap;
|
||||||
|
|
||||||
dest.impMesh = {};
|
dest.impMesh = {};
|
||||||
dest.impShell = {};
|
dest.impShell = {};
|
||||||
dest.impEntity = {};
|
dest.impEntity = {};
|
||||||
ut->group.Add(&dest);
|
ut->group.Add(&dest);
|
||||||
}
|
}
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
for(auto &src : SK.groupOrder) { ut->groupOrder.Add(&src); }
|
||||||
ut->groupOrder.Add(&(SK.groupOrder.elem[i]));
|
|
||||||
}
|
|
||||||
ut->request.ReserveMore(SK.request.n);
|
ut->request.ReserveMore(SK.request.n);
|
||||||
for(i = 0; i < SK.request.n; i++) {
|
for(auto &src : SK.request) { ut->request.Add(&src); }
|
||||||
ut->request.Add(&(SK.request.elem[i]));
|
|
||||||
}
|
|
||||||
ut->constraint.ReserveMore(SK.constraint.n);
|
ut->constraint.ReserveMore(SK.constraint.n);
|
||||||
for(i = 0; i < SK.constraint.n; i++) {
|
for(auto &src : SK.constraint) {
|
||||||
Constraint *src = &(SK.constraint.elem[i]);
|
// Shallow copy
|
||||||
Constraint dest = *src;
|
Constraint dest(src);
|
||||||
ut->constraint.Add(&dest);
|
ut->constraint.Add(&dest);
|
||||||
}
|
}
|
||||||
ut->param.ReserveMore(SK.param.n);
|
ut->param.ReserveMore(SK.param.n);
|
||||||
for(i = 0; i < SK.param.n; i++) {
|
for(auto &src : SK.param) { ut->param.Add(&src); }
|
||||||
ut->param.Add(&(SK.param.elem[i]));
|
|
||||||
}
|
|
||||||
ut->style.ReserveMore(SK.style.n);
|
ut->style.ReserveMore(SK.style.n);
|
||||||
for(i = 0; i < SK.style.n; i++) {
|
for(auto &src : SK.style) { ut->style.Add(&src); }
|
||||||
ut->style.Add(&(SK.style.elem[i]));
|
|
||||||
}
|
|
||||||
ut->activeGroup = SS.GW.activeGroup;
|
ut->activeGroup = SS.GW.activeGroup;
|
||||||
|
|
||||||
uk->write = WRAP(uk->write + 1, MAX_UNDO);
|
uk->write = WRAP(uk->write + 1, MAX_UNDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
||||||
int i;
|
|
||||||
|
|
||||||
ssassert(uk->cnt > 0, "Cannot pop from empty undo stack");
|
ssassert(uk->cnt > 0, "Cannot pop from empty undo stack");
|
||||||
(uk->cnt)--;
|
(uk->cnt)--;
|
||||||
uk->write = WRAP(uk->write - 1, MAX_UNDO);
|
uk->write = WRAP(uk->write - 1, MAX_UNDO);
|
||||||
@ -109,8 +97,8 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
|||||||
UndoState *ut = &(uk->d[uk->write]);
|
UndoState *ut = &(uk->d[uk->write]);
|
||||||
|
|
||||||
// Free everything in the main copy of the program before replacing it
|
// Free everything in the main copy of the program before replacing it
|
||||||
for(i = 0; i < SK.groupOrder.n; i++) {
|
for(hGroup hg : SK.groupOrder) {
|
||||||
Group *g = SK.GetGroup(SK.groupOrder.elem[i]);
|
Group *g = SK.GetGroup(hg);
|
||||||
g->Clear();
|
g->Clear();
|
||||||
}
|
}
|
||||||
SK.group.Clear();
|
SK.group.Clear();
|
||||||
@ -122,8 +110,7 @@ void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) {
|
|||||||
|
|
||||||
// And then do a shallow copy of the state from the undo list
|
// And then do a shallow copy of the state from the undo list
|
||||||
ut->group.MoveSelfInto(&(SK.group));
|
ut->group.MoveSelfInto(&(SK.group));
|
||||||
for(i = 0; i < ut->groupOrder.n; i++)
|
for(auto &gh : ut->groupOrder) { SK.groupOrder.Add(&gh); }
|
||||||
SK.groupOrder.Add(&ut->groupOrder.elem[i]);
|
|
||||||
ut->request.MoveSelfInto(&(SK.request));
|
ut->request.MoveSelfInto(&(SK.request));
|
||||||
ut->constraint.MoveSelfInto(&(SK.constraint));
|
ut->constraint.MoveSelfInto(&(SK.constraint));
|
||||||
ut->param.MoveSelfInto(&(SK.param));
|
ut->param.MoveSelfInto(&(SK.param));
|
||||||
@ -156,12 +143,7 @@ void SolveSpaceUI::UndoClearStack(UndoStack *uk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SolveSpaceUI::UndoClearState(UndoState *ut) {
|
void SolveSpaceUI::UndoClearState(UndoState *ut) {
|
||||||
int i;
|
for(auto &g : ut->group) { g.remap.clear(); }
|
||||||
for(i = 0; i < ut->group.n; i++) {
|
|
||||||
Group *g = &(ut->group.elem[i]);
|
|
||||||
|
|
||||||
g->remap.clear();
|
|
||||||
}
|
|
||||||
ut->group.Clear();
|
ut->group.Clear();
|
||||||
ut->request.Clear();
|
ut->request.Clear();
|
||||||
ut->constraint.Clear();
|
ut->constraint.Clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user