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