Use Range-based for Loops Instead of NextAfter for all IdList Objects
Based on commit '3b395bb5a7' by pjanx Resolves a performance regression of iteration being O(n * log n) rather than O(n).
This commit is contained in:
parent
7674be791e
commit
9dd67c7ba0
@ -138,18 +138,17 @@ void GraphicsWindow::CopySelection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Constraint *c;
|
for(Constraint &c : SK.constraint) {
|
||||||
for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
|
if(!SS.clipboard.ContainsEntity(c.ptA) ||
|
||||||
if(!SS.clipboard.ContainsEntity(c->ptA) ||
|
!SS.clipboard.ContainsEntity(c.ptB) ||
|
||||||
!SS.clipboard.ContainsEntity(c->ptB) ||
|
!SS.clipboard.ContainsEntity(c.entityA) ||
|
||||||
!SS.clipboard.ContainsEntity(c->entityA) ||
|
!SS.clipboard.ContainsEntity(c.entityB) ||
|
||||||
!SS.clipboard.ContainsEntity(c->entityB) ||
|
!SS.clipboard.ContainsEntity(c.entityC) ||
|
||||||
!SS.clipboard.ContainsEntity(c->entityC) ||
|
!SS.clipboard.ContainsEntity(c.entityD) ||
|
||||||
!SS.clipboard.ContainsEntity(c->entityD) ||
|
c.type == Constraint::Type::COMMENT) {
|
||||||
c->type == Constraint::Type::COMMENT) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
SS.clipboard.c.Add(c);
|
SS.clipboard.c.Add(&c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
src/draw.cpp
17
src/draw.cpp
@ -210,16 +210,15 @@ void GraphicsWindow::SelectByMarquee() {
|
|||||||
BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, VERY_NEGATIVE),
|
BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, VERY_NEGATIVE),
|
||||||
Vector::From(orig.mouse.x, orig.mouse.y, VERY_POSITIVE));
|
Vector::From(orig.mouse.x, orig.mouse.y, VERY_POSITIVE));
|
||||||
|
|
||||||
Entity *e;
|
for(Entity &e : SK.entity) {
|
||||||
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
if(e.group != SS.GW.activeGroup) continue;
|
||||||
if(e->group != SS.GW.activeGroup) continue;
|
if(e.IsFace() || e.IsDistance()) continue;
|
||||||
if(e->IsFace() || e->IsDistance()) continue;
|
if(!e.IsVisible()) continue;
|
||||||
if(!e->IsVisible()) continue;
|
|
||||||
|
|
||||||
bool entityHasBBox;
|
bool entityHasBBox;
|
||||||
BBox entityBBox = e->GetOrGenerateScreenBBox(&entityHasBBox);
|
BBox entityBBox = e.GetOrGenerateScreenBBox(&entityHasBBox);
|
||||||
if(entityHasBBox && entityBBox.Overlaps(marqueeBBox)) {
|
if(entityHasBBox && entityBBox.Overlaps(marqueeBBox)) {
|
||||||
MakeSelected(e->h);
|
MakeSelected(e.h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,8 +411,8 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) {
|
|||||||
cached.projRight = projRight;
|
cached.projRight = projRight;
|
||||||
cached.projUp = projUp;
|
cached.projUp = projUp;
|
||||||
cached.scale = scale;
|
cached.scale = scale;
|
||||||
for(Entity *e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
for(Entity &e : SK.entity) {
|
||||||
e->screenBBoxValid = false;
|
e.screenBBoxValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,22 +353,21 @@ void StepFileWriter::ExportSurfacesTo(const Platform::Path &filename) {
|
|||||||
|
|
||||||
advancedFaces = {};
|
advancedFaces = {};
|
||||||
|
|
||||||
SSurface *ss;
|
for(SSurface &ss : shell->surface) {
|
||||||
for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) {
|
if(ss.trim.IsEmpty())
|
||||||
if(ss->trim.IsEmpty())
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Get all of the loops of Beziers that trim our surface (with each
|
// Get all of the loops of Beziers that trim our surface (with each
|
||||||
// Bezier split so that we use the section as t goes from 0 to 1), and
|
// Bezier split so that we use the section as t goes from 0 to 1), and
|
||||||
// the piecewise linearization of those loops in xyz space.
|
// the piecewise linearization of those loops in xyz space.
|
||||||
SBezierList sbl = {};
|
SBezierList sbl = {};
|
||||||
ss->MakeSectionEdgesInto(shell, NULL, &sbl);
|
ss.MakeSectionEdgesInto(shell, NULL, &sbl);
|
||||||
|
|
||||||
// Apply the export scale factor.
|
// Apply the export scale factor.
|
||||||
ss->ScaleSelfBy(1.0/SS.exportScale);
|
ss.ScaleSelfBy(1.0/SS.exportScale);
|
||||||
sbl.ScaleSelfBy(1.0/SS.exportScale);
|
sbl.ScaleSelfBy(1.0/SS.exportScale);
|
||||||
|
|
||||||
ExportSurface(ss, &sbl);
|
ExportSurface(&ss, &sbl);
|
||||||
|
|
||||||
sbl.Clear();
|
sbl.Clear();
|
||||||
}
|
}
|
||||||
|
@ -170,22 +170,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(writer->constraint) {
|
if(writer->constraint) {
|
||||||
Constraint *c;
|
for(Constraint &c : *writer->constraint) {
|
||||||
for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) {
|
if(!writer->NeedToOutput(&c)) continue;
|
||||||
if(!writer->NeedToOutput(c)) continue;
|
switch(c.type) {
|
||||||
switch(c->type) {
|
|
||||||
case Constraint::Type::PT_PT_DISTANCE: {
|
case Constraint::Type::PT_PT_DISTANCE: {
|
||||||
Vector ap = SK.GetEntity(c->ptA)->PointGetNum();
|
Vector ap = SK.GetEntity(c.ptA)->PointGetNum();
|
||||||
Vector bp = SK.GetEntity(c->ptB)->PointGetNum();
|
Vector bp = SK.GetEntity(c.ptB)->PointGetNum();
|
||||||
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset);
|
Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c.disp.offset);
|
||||||
writeAlignedDimension(xfrm(ap), xfrm(bp), xfrm(ref),
|
writeAlignedDimension(xfrm(ap), xfrm(bp), xfrm(ref),
|
||||||
xfrm(ref), c->Label(), c->GetStyle(), c->valA);
|
xfrm(ref), c.Label(), c.GetStyle(), c.valA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Constraint::Type::PT_LINE_DISTANCE: {
|
case Constraint::Type::PT_LINE_DISTANCE: {
|
||||||
Vector pt = SK.GetEntity(c->ptA)->PointGetNum();
|
Vector pt = SK.GetEntity(c.ptA)->PointGetNum();
|
||||||
Entity *line = SK.GetEntity(c->entityA);
|
Entity *line = SK.GetEntity(c.entityA);
|
||||||
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
|
Vector lA = SK.GetEntity(line->point[0])->PointGetNum();
|
||||||
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
|
Vector lB = SK.GetEntity(line->point[1])->PointGetNum();
|
||||||
Vector dl = lB.Minus(lA);
|
Vector dl = lB.Minus(lA);
|
||||||
@ -194,7 +193,7 @@ public:
|
|||||||
|
|
||||||
if(pt.Equals(closest)) break;
|
if(pt.Equals(closest)) break;
|
||||||
|
|
||||||
Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c->disp.offset);
|
Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c.disp.offset);
|
||||||
Vector refClosest = ref.ClosestPointOnLine(lA, dl);
|
Vector refClosest = ref.ClosestPointOnLine(lA, dl);
|
||||||
|
|
||||||
double ddl = dl.Dot(dl);
|
double ddl = dl.Dot(dl);
|
||||||
@ -209,54 +208,54 @@ public:
|
|||||||
|
|
||||||
Vector xdl = xfrm(lB).Minus(xfrm(lA));
|
Vector xdl = xfrm(lB).Minus(xfrm(lA));
|
||||||
writeLinearDimension(xfrm(pt), xfrm(refClosest), xfrm(ref),
|
writeLinearDimension(xfrm(pt), xfrm(refClosest), xfrm(ref),
|
||||||
xfrm(ref), c->Label(),
|
xfrm(ref), c.Label(),
|
||||||
atan2(xdl.y, xdl.x) / PI * 180.0 + 90.0, 0.0,
|
atan2(xdl.y, xdl.x) / PI * 180.0 + 90.0, 0.0,
|
||||||
c->GetStyle(), c->valA);
|
c.GetStyle(), c.valA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Constraint::Type::DIAMETER: {
|
case Constraint::Type::DIAMETER: {
|
||||||
Entity *circle = SK.GetEntity(c->entityA);
|
Entity *circle = SK.GetEntity(c.entityA);
|
||||||
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
|
Vector center = SK.GetEntity(circle->point[0])->PointGetNum();
|
||||||
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
|
Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum();
|
||||||
Vector n = q.RotationN().WithMagnitude(1);
|
Vector n = q.RotationN().WithMagnitude(1);
|
||||||
double r = circle->CircleGetRadiusNum();
|
double r = circle->CircleGetRadiusNum();
|
||||||
|
|
||||||
Vector ref = center.Plus(c->disp.offset);
|
Vector ref = center.Plus(c.disp.offset);
|
||||||
// Force the label into the same plane as the circle.
|
// Force the label into the same plane as the circle.
|
||||||
ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));
|
ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center)));
|
||||||
|
|
||||||
Vector rad = ref.Minus(center).WithMagnitude(r);
|
Vector rad = ref.Minus(center).WithMagnitude(r);
|
||||||
if(/*isRadius*/c->other) {
|
if(/*isRadius*/c.other) {
|
||||||
writeRadialDimension(
|
writeRadialDimension(
|
||||||
xfrm(center), xfrm(center.Plus(rad)),
|
xfrm(center), xfrm(center.Plus(rad)),
|
||||||
xfrm(ref), c->Label(), c->GetStyle(), c->valA);
|
xfrm(ref), c.Label(), c.GetStyle(), c.valA);
|
||||||
} else {
|
} else {
|
||||||
writeDiametricDimension(
|
writeDiametricDimension(
|
||||||
xfrm(center.Minus(rad)), xfrm(center.Plus(rad)),
|
xfrm(center.Minus(rad)), xfrm(center.Plus(rad)),
|
||||||
xfrm(ref), c->Label(), c->GetStyle(), c->valA);
|
xfrm(ref), c.Label(), c.GetStyle(), c.valA);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Constraint::Type::ANGLE: {
|
case Constraint::Type::ANGLE: {
|
||||||
Entity *a = SK.GetEntity(c->entityA);
|
Entity *a = SK.GetEntity(c.entityA);
|
||||||
Entity *b = SK.GetEntity(c->entityB);
|
Entity *b = SK.GetEntity(c.entityB);
|
||||||
|
|
||||||
Vector a0 = a->VectorGetStartPoint();
|
Vector a0 = a->VectorGetStartPoint();
|
||||||
Vector b0 = b->VectorGetStartPoint();
|
Vector b0 = b->VectorGetStartPoint();
|
||||||
Vector da = a->VectorGetNum();
|
Vector da = a->VectorGetNum();
|
||||||
Vector db = b->VectorGetNum();
|
Vector db = b->VectorGetNum();
|
||||||
if(/*otherAngle*/c->other) {
|
if(/*otherAngle*/c.other) {
|
||||||
a0 = a0.Plus(da);
|
a0 = a0.Plus(da);
|
||||||
da = da.ScaledBy(-1);
|
da = da.ScaledBy(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool skew = false;
|
bool skew = false;
|
||||||
Vector ref = c->disp.offset;
|
Vector ref = c.disp.offset;
|
||||||
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da), b0, b0.Plus(db),
|
Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da), b0, b0.Plus(db),
|
||||||
&skew);
|
&skew);
|
||||||
if(!skew) ref = pi.Plus(c->disp.offset);
|
if(!skew) ref = pi.Plus(c.disp.offset);
|
||||||
|
|
||||||
Vector norm = da.Cross(db);
|
Vector norm = da.Cross(db);
|
||||||
Vector dna = norm.Cross(da).WithMagnitude(1.0);
|
Vector dna = norm.Cross(da).WithMagnitude(1.0);
|
||||||
@ -277,7 +276,7 @@ public:
|
|||||||
Vector bisect = da.WithMagnitude(1.0).ScaledBy(cos(thetaf / 2.0)).Plus(
|
Vector bisect = da.WithMagnitude(1.0).ScaledBy(cos(thetaf / 2.0)).Plus(
|
||||||
dna.ScaledBy(sin(thetaf / 2.0)));
|
dna.ScaledBy(sin(thetaf / 2.0)));
|
||||||
|
|
||||||
ref = pi.Plus(bisect.WithMagnitude(c->disp.offset.Magnitude()));
|
ref = pi.Plus(bisect.WithMagnitude(c.disp.offset.Magnitude()));
|
||||||
|
|
||||||
// Get lines again to write exact line.
|
// Get lines again to write exact line.
|
||||||
a0 = a->VectorGetStartPoint();
|
a0 = a->VectorGetStartPoint();
|
||||||
@ -287,15 +286,15 @@ public:
|
|||||||
|
|
||||||
writeAngularDimension(
|
writeAngularDimension(
|
||||||
xfrm(a0), xfrm(a0.Plus(da)), xfrm(b0), xfrm(b0.Plus(db)), xfrm(ref),
|
xfrm(a0), xfrm(a0.Plus(da)), xfrm(b0), xfrm(b0.Plus(db)), xfrm(ref),
|
||||||
xfrm(ref), c->Label(), c->GetStyle(), c->valA);
|
xfrm(ref), c.Label(), c.GetStyle(), c.valA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Constraint::Type::COMMENT: {
|
case Constraint::Type::COMMENT: {
|
||||||
Style *st = SK.style.FindById(c->GetStyle());
|
Style *st = SK.style.FindById(c.GetStyle());
|
||||||
writeText(xfrm(c->disp.offset), c->Label(),
|
writeText(xfrm(c.disp.offset), c.Label(),
|
||||||
Style::TextHeight(c->GetStyle()) / SS.GW.scale,
|
Style::TextHeight(c.GetStyle()) / SS.GW.scale,
|
||||||
st->textAngle, st->textOrigin, c->GetStyle());
|
st->textAngle, st->textOrigin, c.GetStyle());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
src/file.cpp
30
src/file.cpp
@ -354,19 +354,18 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SShell *s = &g->runningShell;
|
SShell *s = &g->runningShell;
|
||||||
SSurface *srf;
|
for(SSurface &srf : s->surface) {
|
||||||
for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) {
|
|
||||||
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
|
fprintf(fh, "Surface %08x %08x %08x %d %d\n",
|
||||||
srf->h.v, srf->color.ToPackedInt(), srf->face, srf->degm, srf->degn);
|
srf.h.v, srf.color.ToPackedInt(), srf.face, srf.degm, srf.degn);
|
||||||
for(i = 0; i <= srf->degm; i++) {
|
for(i = 0; i <= srf.degm; i++) {
|
||||||
for(j = 0; j <= srf->degn; j++) {
|
for(j = 0; j <= srf.degn; j++) {
|
||||||
fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n",
|
fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n",
|
||||||
i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]);
|
i, j, CO(srf.ctrl[i][j]), srf.weight[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STrimBy *stb;
|
STrimBy *stb;
|
||||||
for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) {
|
for(stb = srf.trim.First(); stb; stb = srf.trim.NextAfter(stb)) {
|
||||||
fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n",
|
||||||
stb->curve.v, stb->backwards ? 1 : 0,
|
stb->curve.v, stb->backwards ? 1 : 0,
|
||||||
CO(stb->start), CO(stb->finish));
|
CO(stb->start), CO(stb->finish));
|
||||||
@ -374,21 +373,20 @@ bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) {
|
|||||||
|
|
||||||
fprintf(fh, "AddSurface\n");
|
fprintf(fh, "AddSurface\n");
|
||||||
}
|
}
|
||||||
SCurve *sc;
|
for(SCurve &sc : s->curve) {
|
||||||
for(sc = s->curve.First(); sc; sc = s->curve.NextAfter(sc)) {
|
|
||||||
fprintf(fh, "Curve %08x %d %d %08x %08x\n",
|
fprintf(fh, "Curve %08x %d %d %08x %08x\n",
|
||||||
sc->h.v,
|
sc.h.v,
|
||||||
sc->isExact ? 1 : 0, sc->exact.deg,
|
sc.isExact ? 1 : 0, sc.exact.deg,
|
||||||
sc->surfA.v, sc->surfB.v);
|
sc.surfA.v, sc.surfB.v);
|
||||||
|
|
||||||
if(sc->isExact) {
|
if(sc.isExact) {
|
||||||
for(i = 0; i <= sc->exact.deg; i++) {
|
for(i = 0; i <= sc.exact.deg; i++) {
|
||||||
fprintf(fh, "CCtrl %d %.20f %.20f %.20f Weight %.20f\n",
|
fprintf(fh, "CCtrl %d %.20f %.20f %.20f Weight %.20f\n",
|
||||||
i, CO(sc->exact.ctrl[i]), sc->exact.weight[i]);
|
i, CO(sc.exact.ctrl[i]), sc.exact.weight[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCurvePt *scpt;
|
SCurvePt *scpt;
|
||||||
for(scpt = sc->pts.First(); scpt; scpt = sc->pts.NextAfter(scpt)) {
|
for(scpt = sc.pts.First(); scpt; scpt = sc.pts.NextAfter(scpt)) {
|
||||||
fprintf(fh, "CurvePt %d %.20f %.20f %.20f\n",
|
fprintf(fh, "CurvePt %d %.20f %.20f %.20f\n",
|
||||||
scpt->vertex ? 1 : 0, CO(scpt->p));
|
scpt->vertex ? 1 : 0, CO(scpt->p));
|
||||||
}
|
}
|
||||||
|
@ -968,20 +968,19 @@ void GraphicsWindow::ForceTextWindowShown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWindow::DeleteTaggedRequests() {
|
void GraphicsWindow::DeleteTaggedRequests() {
|
||||||
Request *r;
|
|
||||||
// Delete any requests that were affected by this deletion.
|
// Delete any requests that were affected by this deletion.
|
||||||
for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) {
|
for(Request &r : SK.request) {
|
||||||
if(r->workplane == Entity::FREE_IN_3D) continue;
|
if(r.workplane == Entity::FREE_IN_3D) continue;
|
||||||
if(!r->workplane.isFromRequest()) continue;
|
if(!r.workplane.isFromRequest()) continue;
|
||||||
Request *wrkpl = SK.GetRequest(r->workplane.request());
|
Request *wrkpl = SK.GetRequest(r.workplane.request());
|
||||||
if(wrkpl->tag)
|
if(wrkpl->tag)
|
||||||
r->tag = 1;
|
r.tag = 1;
|
||||||
}
|
}
|
||||||
// Rewrite any point-coincident constraints that were affected by this
|
// Rewrite any point-coincident constraints that were affected by this
|
||||||
// deletion.
|
// deletion.
|
||||||
for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) {
|
for(Request &r : SK.request) {
|
||||||
if(!r->tag) continue;
|
if(!r.tag) continue;
|
||||||
FixConstraintsForRequestBeingDeleted(r->h);
|
FixConstraintsForRequestBeingDeleted(r.h);
|
||||||
}
|
}
|
||||||
// and then delete the tagged requests.
|
// and then delete the tagged requests.
|
||||||
SK.request.RemoveTagged();
|
SK.request.RemoveTagged();
|
||||||
@ -1045,9 +1044,8 @@ void GraphicsWindow::MenuEdit(Command id) {
|
|||||||
SS.centerOfMass.draw = false;
|
SS.centerOfMass.draw = false;
|
||||||
// This clears the marks drawn to indicate which points are
|
// This clears the marks drawn to indicate which points are
|
||||||
// still free to drag.
|
// still free to drag.
|
||||||
Param *p;
|
for(Param &p : SK.param) {
|
||||||
for(p = SK.param.First(); p; p = SK.param.NextAfter(p)) {
|
p.free = false;
|
||||||
p->free = false;
|
|
||||||
}
|
}
|
||||||
if(SS.exportMode) {
|
if(SS.exportMode) {
|
||||||
SS.exportMode = false;
|
SS.exportMode = false;
|
||||||
@ -1057,13 +1055,12 @@ void GraphicsWindow::MenuEdit(Command id) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SELECT_ALL: {
|
case Command::SELECT_ALL: {
|
||||||
Entity *e;
|
for(Entity &e : SK.entity) {
|
||||||
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
if(e.group != SS.GW.activeGroup) continue;
|
||||||
if(e->group != SS.GW.activeGroup) continue;
|
if(e.IsFace() || e.IsDistance()) continue;
|
||||||
if(e->IsFace() || e->IsDistance()) continue;
|
if(!e.IsVisible()) continue;
|
||||||
if(!e->IsVisible()) continue;
|
|
||||||
|
|
||||||
SS.GW.MakeSelected(e->h);
|
SS.GW.MakeSelected(e.h);
|
||||||
}
|
}
|
||||||
SS.GW.Invalidate();
|
SS.GW.Invalidate();
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
@ -1071,24 +1068,23 @@ void GraphicsWindow::MenuEdit(Command id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case Command::SELECT_CHAIN: {
|
case Command::SELECT_CHAIN: {
|
||||||
Entity *e;
|
|
||||||
int newlySelected = 0;
|
int newlySelected = 0;
|
||||||
bool didSomething;
|
bool didSomething;
|
||||||
do {
|
do {
|
||||||
didSomething = false;
|
didSomething = false;
|
||||||
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
for(Entity &e : SK.entity) {
|
||||||
if(e->group != SS.GW.activeGroup) continue;
|
if(e.group != SS.GW.activeGroup) continue;
|
||||||
if(!e->HasEndpoints()) continue;
|
if(!e.HasEndpoints()) continue;
|
||||||
if(!e->IsVisible()) continue;
|
if(!e.IsVisible()) continue;
|
||||||
|
|
||||||
Vector st = e->EndpointStart(),
|
Vector st = e.EndpointStart(),
|
||||||
fi = e->EndpointFinish();
|
fi = e.EndpointFinish();
|
||||||
|
|
||||||
bool onChain = false, alreadySelected = false;
|
bool onChain = false, alreadySelected = false;
|
||||||
List<Selection> *ls = &(SS.GW.selection);
|
List<Selection> *ls = &(SS.GW.selection);
|
||||||
for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) {
|
for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) {
|
||||||
if(!s->entity.v) continue;
|
if(!s->entity.v) continue;
|
||||||
if(s->entity == e->h) {
|
if(s->entity == e.h) {
|
||||||
alreadySelected = true;
|
alreadySelected = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1105,7 +1101,7 @@ void GraphicsWindow::MenuEdit(Command id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(onChain && !alreadySelected) {
|
if(onChain && !alreadySelected) {
|
||||||
SS.GW.MakeSelected(e->h);
|
SS.GW.MakeSelected(e.h);
|
||||||
newlySelected++;
|
newlySelected++;
|
||||||
didSomething = true;
|
didSomething = true;
|
||||||
}
|
}
|
||||||
|
@ -83,13 +83,12 @@ void Group::GenerateLoops() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SShell::RemapFaces(Group *g, int remap) {
|
void SShell::RemapFaces(Group *g, int remap) {
|
||||||
SSurface *ss;
|
for(SSurface &ss : surface){
|
||||||
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)){
|
hEntity face = { ss.face };
|
||||||
hEntity face = { ss->face };
|
|
||||||
if(face == Entity::NO_ENTITY) continue;
|
if(face == Entity::NO_ENTITY) continue;
|
||||||
|
|
||||||
face = g->Remap(face, remap);
|
face = g->Remap(face, remap);
|
||||||
ss->face = face.v;
|
ss.face = face.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,13 +291,12 @@ void Group::GenerateShellAndMesh() {
|
|||||||
// So these are the sides
|
// So these are the sides
|
||||||
if(ss->degm != 1 || ss->degn != 1) continue;
|
if(ss->degm != 1 || ss->degn != 1) continue;
|
||||||
|
|
||||||
Entity *e;
|
for(Entity &e : SK.entity) {
|
||||||
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
if(e.group != opA) continue;
|
||||||
if(e->group != opA) continue;
|
if(e.type != Entity::Type::LINE_SEGMENT) continue;
|
||||||
if(e->type != Entity::Type::LINE_SEGMENT) continue;
|
|
||||||
|
|
||||||
Vector a = SK.GetEntity(e->point[0])->PointGetNum(),
|
Vector a = SK.GetEntity(e.point[0])->PointGetNum(),
|
||||||
b = SK.GetEntity(e->point[1])->PointGetNum();
|
b = SK.GetEntity(e.point[1])->PointGetNum();
|
||||||
a = a.Plus(ttop);
|
a = a.Plus(ttop);
|
||||||
b = b.Plus(ttop);
|
b = b.Plus(ttop);
|
||||||
// Could get taken backwards, so check all cases.
|
// Could get taken backwards, so check all cases.
|
||||||
@ -307,7 +305,7 @@ void Group::GenerateShellAndMesh() {
|
|||||||
(a.Equals(ss->ctrl[0][1]) && b.Equals(ss->ctrl[1][1])) ||
|
(a.Equals(ss->ctrl[0][1]) && b.Equals(ss->ctrl[1][1])) ||
|
||||||
(b.Equals(ss->ctrl[0][1]) && a.Equals(ss->ctrl[1][1])))
|
(b.Equals(ss->ctrl[0][1]) && a.Equals(ss->ctrl[1][1])))
|
||||||
{
|
{
|
||||||
face = Remap(e->h, REMAP_LINE_TO_FACE);
|
face = Remap(e.h, REMAP_LINE_TO_FACE);
|
||||||
ss->face = face.v;
|
ss->face = face.v;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -50,38 +50,36 @@ void GraphicsWindow::FixConstraintsForRequestBeingDeleted(hRequest hr) {
|
|||||||
Request *r = SK.GetRequest(hr);
|
Request *r = SK.GetRequest(hr);
|
||||||
if(r->group != SS.GW.activeGroup) return;
|
if(r->group != SS.GW.activeGroup) return;
|
||||||
|
|
||||||
Entity *e;
|
for(Entity &e : SK.entity) {
|
||||||
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
if(!(e.h.isFromRequest())) continue;
|
||||||
if(!(e->h.isFromRequest())) continue;
|
if(e.h.request() != hr) continue;
|
||||||
if(e->h.request() != hr) continue;
|
|
||||||
|
|
||||||
if(e->type != Entity::Type::POINT_IN_2D &&
|
if(e.type != Entity::Type::POINT_IN_2D &&
|
||||||
e->type != Entity::Type::POINT_IN_3D)
|
e.type != Entity::Type::POINT_IN_3D)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a point generated by the request being deleted; so fix
|
// This is a point generated by the request being deleted; so fix
|
||||||
// the constraints for that.
|
// the constraints for that.
|
||||||
FixConstraintsForPointBeingDeleted(e->h);
|
FixConstraintsForPointBeingDeleted(e.h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
|
void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) {
|
||||||
List<hEntity> ld = {};
|
List<hEntity> ld = {};
|
||||||
|
|
||||||
Constraint *c;
|
|
||||||
SK.constraint.ClearTags();
|
SK.constraint.ClearTags();
|
||||||
for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
|
for(Constraint &c : SK.constraint) {
|
||||||
if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
|
if(c.type != Constraint::Type::POINTS_COINCIDENT) continue;
|
||||||
if(c->group != SS.GW.activeGroup) continue;
|
if(c.group != SS.GW.activeGroup) continue;
|
||||||
|
|
||||||
if(c->ptA == hpt) {
|
if(c.ptA == hpt) {
|
||||||
ld.Add(&(c->ptB));
|
ld.Add(&(c.ptB));
|
||||||
c->tag = 1;
|
c.tag = 1;
|
||||||
}
|
}
|
||||||
if(c->ptB == hpt) {
|
if(c.ptB == hpt) {
|
||||||
ld.Add(&(c->ptA));
|
ld.Add(&(c.ptA));
|
||||||
c->tag = 1;
|
c.tag = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remove constraints without waiting for regeneration; this way
|
// Remove constraints without waiting for regeneration; this way
|
||||||
@ -225,21 +223,21 @@ void GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t,
|
|||||||
// happens to exist, then constrain that point coincident to hpt.
|
// happens to exist, then constrain that point coincident to hpt.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GraphicsWindow::ParametricCurve::ConstrainPointIfCoincident(hEntity hpt) {
|
void GraphicsWindow::ParametricCurve::ConstrainPointIfCoincident(hEntity hpt) {
|
||||||
Entity *e, *pt;
|
Entity *pt;
|
||||||
pt = SK.GetEntity(hpt);
|
pt = SK.GetEntity(hpt);
|
||||||
Vector ev, ptv;
|
Vector ev, ptv;
|
||||||
ptv = pt->PointGetNum();
|
ptv = pt->PointGetNum();
|
||||||
|
|
||||||
for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) {
|
for(Entity &e : SK.entity) {
|
||||||
if(e->h == pt->h) continue;
|
if(e.h == pt->h) continue;
|
||||||
if(!e->IsPoint()) continue;
|
if(!e.IsPoint()) continue;
|
||||||
if(e->group != pt->group) continue;
|
if(e.group != pt->group) continue;
|
||||||
if(e->workplane != pt->workplane) continue;
|
if(e.workplane != pt->workplane) continue;
|
||||||
|
|
||||||
ev = e->PointGetNum();
|
ev = e.PointGetNum();
|
||||||
if(!ev.Equals(ptv)) continue;
|
if(!ev.Equals(ptv)) continue;
|
||||||
|
|
||||||
Constraint::ConstrainCoincident(hpt, e->h);
|
Constraint::ConstrainCoincident(hpt, e.h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -713,11 +713,12 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||||||
|
|
||||||
if(gs.points == 1) {
|
if(gs.points == 1) {
|
||||||
Entity *p = SK.GetEntity(gs.point[0]);
|
Entity *p = SK.GetEntity(gs.point[0]);
|
||||||
Constraint *c;
|
Constraint *c = nullptr;
|
||||||
IdList<Constraint,hConstraint> *lc = &(SK.constraint);
|
IdList<Constraint,hConstraint> *lc = &(SK.constraint);
|
||||||
for(c = lc->First(); c; c = lc->NextAfter(c)) {
|
for(Constraint &ci : *lc) {
|
||||||
if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
|
if(ci.type != Constraint::Type::POINTS_COINCIDENT) continue;
|
||||||
if(c->ptA == p->h || c->ptB == p->h) {
|
if(ci.ptA == p->h || ci.ptB == p->h) {
|
||||||
|
c = &ci;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -727,11 +728,10 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
|||||||
|
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
SK.constraint.ClearTags();
|
SK.constraint.ClearTags();
|
||||||
Constraint *c;
|
for(Constraint &c : SK.constraint) {
|
||||||
for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) {
|
if(c.type != Constraint::Type::POINTS_COINCIDENT) continue;
|
||||||
if(c->type != Constraint::Type::POINTS_COINCIDENT) continue;
|
if(c.ptA == p->h || c.ptB == p->h) {
|
||||||
if(c->ptA == p->h || c->ptB == p->h) {
|
c.tag = 1;
|
||||||
c->tag = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SK.constraint.RemoveTagged();
|
SK.constraint.RemoveTagged();
|
||||||
|
@ -521,20 +521,19 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
|||||||
SEdgeList inter = {};
|
SEdgeList inter = {};
|
||||||
|
|
||||||
SSurface *ss;
|
SSurface *ss;
|
||||||
SCurve *sc;
|
for(SCurve &sc : into->curve) {
|
||||||
for(sc = into->curve.First(); sc; sc = into->curve.NextAfter(sc)) {
|
if(sc.source != SCurve::Source::INTERSECTION) continue;
|
||||||
if(sc->source != SCurve::Source::INTERSECTION) continue;
|
|
||||||
if(opA) {
|
if(opA) {
|
||||||
if(sc->surfA != h) continue;
|
if(sc.surfA != h) continue;
|
||||||
ss = shb->surface.FindById(sc->surfB);
|
ss = shb->surface.FindById(sc.surfB);
|
||||||
} else {
|
} else {
|
||||||
if(sc->surfB != h) continue;
|
if(sc.surfB != h) continue;
|
||||||
ss = sha->surface.FindById(sc->surfA);
|
ss = sha->surface.FindById(sc.surfA);
|
||||||
}
|
}
|
||||||
int i;
|
int i;
|
||||||
for(i = 1; i < sc->pts.n; i++) {
|
for(i = 1; i < sc.pts.n; i++) {
|
||||||
Vector a = sc->pts[i-1].p,
|
Vector a = sc.pts[i-1].p,
|
||||||
b = sc->pts[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));
|
||||||
@ -560,9 +559,9 @@ SSurface SSurface::MakeCopyTrimAgainst(SShell *parent,
|
|||||||
bkwds = !bkwds;
|
bkwds = !bkwds;
|
||||||
}
|
}
|
||||||
if(bkwds) {
|
if(bkwds) {
|
||||||
inter.AddEdge(tb, ta, sc->h.v, 1);
|
inter.AddEdge(tb, ta, sc.h.v, 1);
|
||||||
} else {
|
} else {
|
||||||
inter.AddEdge(ta, tb, sc->h.v, 0);
|
inter.AddEdge(ta, tb, sc.h.v, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -711,20 +710,18 @@ void SShell::MakeIntersectionCurvesAgainst(SShell *agnst, SShell *into) {
|
|||||||
for(int i = 0; i< surface.n; i++) {
|
for(int i = 0; i< surface.n; i++) {
|
||||||
SSurface *sa = &surface[i];
|
SSurface *sa = &surface[i];
|
||||||
|
|
||||||
SSurface *sb;
|
for(SSurface &sb : agnst->surface){
|
||||||
for(sb = agnst->surface.First(); sb; sb = agnst->surface.NextAfter(sb)){
|
|
||||||
// Intersect every surface from our shell against every surface
|
// Intersect every surface from our shell against every surface
|
||||||
// from agnst; this will add zero or more curves to the curve
|
// from agnst; this will add zero or more curves to the curve
|
||||||
// list for into.
|
// list for into.
|
||||||
sa->IntersectAgainst(sb, this, agnst, into);
|
sa->IntersectAgainst(&sb, this, agnst, into);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShell::CleanupAfterBoolean() {
|
void SShell::CleanupAfterBoolean() {
|
||||||
SSurface *ss;
|
for(SSurface &ss : surface) {
|
||||||
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
|
ss.edges.Clear();
|
||||||
ss->edges.Clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,10 +731,9 @@ void SShell::CleanupAfterBoolean() {
|
|||||||
// by their new IDs.
|
// by their new IDs.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SShell::RewriteSurfaceHandlesForCurves(SShell *a, SShell *b) {
|
void SShell::RewriteSurfaceHandlesForCurves(SShell *a, SShell *b) {
|
||||||
SCurve *sc;
|
for(SCurve &sc : curve) {
|
||||||
for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
|
sc.surfA = sc.GetSurfaceA(a, b)->newH,
|
||||||
sc->surfA = sc->GetSurfaceA(a, b)->newH,
|
sc.surfB = sc.GetSurfaceB(a, b)->newH;
|
||||||
sc->surfB = sc->GetSurfaceB(a, b)->newH;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,32 +755,32 @@ void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) {
|
|||||||
// First, copy over all the curves. Note which shell (a or b) each curve
|
// First, copy over all the curves. Note which shell (a or b) each curve
|
||||||
// came from, but assign it a new ID.
|
// came from, but assign it a new ID.
|
||||||
curve.ReserveMore(a->curve.n + b->curve.n);
|
curve.ReserveMore(a->curve.n + b->curve.n);
|
||||||
SCurve *c, cn;
|
SCurve cn;
|
||||||
for(i = 0; i < 2; i++) {
|
for(i = 0; i < 2; i++) {
|
||||||
ab = (i == 0) ? a : b;
|
ab = (i == 0) ? a : b;
|
||||||
for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) {
|
for(SCurve &c : ab->curve) {
|
||||||
cn = SCurve::FromTransformationOf(c, t, q, 1.0);
|
cn = SCurve::FromTransformationOf(&c, t, q, 1.0);
|
||||||
cn.source = (i == 0) ? SCurve::Source::A : SCurve::Source::B;
|
cn.source = (i == 0) ? SCurve::Source::A : SCurve::Source::B;
|
||||||
// surfA and surfB are wrong now, and we can't fix them until
|
// surfA and surfB are wrong now, and we can't fix them until
|
||||||
// we've assigned IDs to the surfaces. So we'll get that later.
|
// we've assigned IDs to the surfaces. So we'll get that later.
|
||||||
c->newH = curve.AddAndAssignId(&cn);
|
c.newH = curve.AddAndAssignId(&cn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Likewise copy over all the surfaces.
|
// Likewise copy over all the surfaces.
|
||||||
surface.ReserveMore(a->surface.n + b->surface.n);
|
surface.ReserveMore(a->surface.n + b->surface.n);
|
||||||
SSurface *s, sn;
|
SSurface sn;
|
||||||
for(i = 0; i < 2; i++) {
|
for(i = 0; i < 2; i++) {
|
||||||
ab = (i == 0) ? a : b;
|
ab = (i == 0) ? a : b;
|
||||||
for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) {
|
for(SSurface &s : ab->surface) {
|
||||||
sn = SSurface::FromTransformationOf(s, t, q, 1.0, /*includingTrims=*/true);
|
sn = SSurface::FromTransformationOf(&s, t, q, 1.0, /*includingTrims=*/true);
|
||||||
// All the trim curve IDs get rewritten; we know the new handles
|
// All the trim curve IDs get rewritten; we know the new handles
|
||||||
// to the curves since we recorded them in the previous step.
|
// to the curves since we recorded them in the previous step.
|
||||||
STrimBy *stb;
|
STrimBy *stb;
|
||||||
for(stb = sn.trim.First(); stb; stb = sn.trim.NextAfter(stb)) {
|
for(stb = sn.trim.First(); stb; stb = sn.trim.NextAfter(stb)) {
|
||||||
stb->curve = ab->curve.FindById(stb->curve)->newH;
|
stb->curve = ab->curve.FindById(stb->curve)->newH;
|
||||||
}
|
}
|
||||||
s->newH = surface.AddAndAssignId(&sn);
|
s.newH = surface.AddAndAssignId(&sn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,12 +805,11 @@ void SShell::MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type) {
|
|||||||
// the surfaces in B (which is all of the intersection curves).
|
// the surfaces in B (which is all of the intersection curves).
|
||||||
a->MakeIntersectionCurvesAgainst(b, this);
|
a->MakeIntersectionCurvesAgainst(b, this);
|
||||||
|
|
||||||
SCurve *sc;
|
for(SCurve &sc : curve) {
|
||||||
for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
|
SSurface *srfA = sc.GetSurfaceA(a, b),
|
||||||
SSurface *srfA = sc->GetSurfaceA(a, b),
|
*srfB = sc.GetSurfaceB(a, b);
|
||||||
*srfB = sc->GetSurfaceB(a, b);
|
|
||||||
|
|
||||||
sc->RemoveShortSegments(srfA, srfB);
|
sc.RemoveShortSegments(srfA, srfB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// And clean up the piecewise linear things we made as a calculation aid
|
// And clean up the piecewise linear things we made as a calculation aid
|
||||||
|
@ -58,10 +58,9 @@ void SShell::MergeCoincidentSurfaces() {
|
|||||||
|
|
||||||
// All the references to this surface get replaced with the
|
// All the references to this surface get replaced with the
|
||||||
// new srf
|
// new srf
|
||||||
SCurve *sc;
|
for(SCurve &sc : curve) {
|
||||||
for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) {
|
if(sc.surfA == sj->h) sc.surfA = si->h;
|
||||||
if(sc->surfA == sj->h) sc->surfA = si->h;
|
if(sc.surfB == sj->h) sc.surfB = si->h;
|
||||||
if(sc->surfB == sj->h) sc->surfB = si->h;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,9 +381,8 @@ void SShell::AllPointsIntersecting(Vector a, Vector b,
|
|||||||
List<SInter> *il,
|
List<SInter> *il,
|
||||||
bool asSegment, bool trimmed, bool inclTangent)
|
bool asSegment, bool trimmed, bool inclTangent)
|
||||||
{
|
{
|
||||||
SSurface *ss;
|
for(SSurface &ss : surface) {
|
||||||
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
|
ss.AllPointsIntersecting(a, b, il,
|
||||||
ss->AllPointsIntersecting(a, b, il,
|
|
||||||
asSegment, trimmed, inclTangent);
|
asSegment, trimmed, inclTangent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,11 +433,10 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
// First, check for edge-on-edge
|
// First, check for edge-on-edge
|
||||||
int edge_inters = 0;
|
int edge_inters = 0;
|
||||||
Vector inter_surf_n[2], inter_edge_n[2];
|
Vector inter_surf_n[2], inter_edge_n[2];
|
||||||
SSurface *srf;
|
for(SSurface &srf : surface) {
|
||||||
for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
|
if(srf.LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
|
||||||
if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
|
|
||||||
|
|
||||||
SEdgeList *sel = &(srf->edges);
|
SEdgeList *sel = &(srf.edges);
|
||||||
SEdge *se;
|
SEdge *se;
|
||||||
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
|
for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) {
|
||||||
if((ea.Equals(se->a) && eb.Equals(se->b)) ||
|
if((ea.Equals(se->a) && eb.Equals(se->b)) ||
|
||||||
@ -448,9 +446,9 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
if(edge_inters < 2) {
|
if(edge_inters < 2) {
|
||||||
// Edge-on-edge case
|
// Edge-on-edge case
|
||||||
Point2d pm;
|
Point2d pm;
|
||||||
srf->ClosestPointTo(p, &pm, /*mustConverge=*/false);
|
srf.ClosestPointTo(p, &pm, /*mustConverge=*/false);
|
||||||
// A vector normal to the surface, at the intersection point
|
// A vector normal to the surface, at the intersection point
|
||||||
inter_surf_n[edge_inters] = srf->NormalAt(pm);
|
inter_surf_n[edge_inters] = srf.NormalAt(pm);
|
||||||
// A vector normal to the intersecting edge (but within the
|
// A vector normal to the intersecting edge (but within the
|
||||||
// intersecting surface) at the intersection point, pointing
|
// intersecting surface) at the intersection point, pointing
|
||||||
// out.
|
// out.
|
||||||
@ -520,25 +518,25 @@ bool SShell::ClassifyEdge(Class *indir, Class *outdir,
|
|||||||
// are on surface) and for numerical stability, so we don't pick up
|
// are on surface) and for numerical stability, so we don't pick up
|
||||||
// the additional error from the line intersection.
|
// the additional error from the line intersection.
|
||||||
|
|
||||||
for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) {
|
for(SSurface &srf : surface) {
|
||||||
if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
|
if(srf.LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue;
|
||||||
|
|
||||||
Point2d puv;
|
Point2d puv;
|
||||||
srf->ClosestPointTo(p, &(puv.x), &(puv.y), /*mustConverge=*/false);
|
srf.ClosestPointTo(p, &(puv.x), &(puv.y), /*mustConverge=*/false);
|
||||||
Vector pp = srf->PointAt(puv);
|
Vector pp = srf.PointAt(puv);
|
||||||
|
|
||||||
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
|
if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue;
|
||||||
Point2d dummy = { 0, 0 };
|
Point2d dummy = { 0, 0 };
|
||||||
SBspUv::Class c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::Class::OUTSIDE;
|
SBspUv::Class c = (srf.bsp) ? srf.bsp->ClassifyPoint(puv, dummy, &srf) : SBspUv::Class::OUTSIDE;
|
||||||
if(c == SBspUv::Class::OUTSIDE) continue;
|
if(c == SBspUv::Class::OUTSIDE) continue;
|
||||||
|
|
||||||
// Edge-on-face (unless edge-on-edge above superceded)
|
// Edge-on-face (unless edge-on-edge above superceded)
|
||||||
Point2d pin, pout;
|
Point2d pin, pout;
|
||||||
srf->ClosestPointTo(p.Plus(edge_n_in), &pin, /*mustConverge=*/false);
|
srf.ClosestPointTo(p.Plus(edge_n_in), &pin, /*mustConverge=*/false);
|
||||||
srf->ClosestPointTo(p.Plus(edge_n_out), &pout, /*mustConverge=*/false);
|
srf.ClosestPointTo(p.Plus(edge_n_out), &pout, /*mustConverge=*/false);
|
||||||
|
|
||||||
Vector surf_n_in = srf->NormalAt(pin),
|
Vector surf_n_in = srf.NormalAt(pin),
|
||||||
surf_n_out = srf->NormalAt(pout);
|
surf_n_out = srf.NormalAt(pout);
|
||||||
|
|
||||||
*indir = ClassifyRegion(edge_n_in, surf_n_in, surf_n);
|
*indir = ClassifyRegion(edge_n_in, surf_n_in, surf_n);
|
||||||
*outdir = ClassifyRegion(edge_n_out, surf_n_out, surf_n);
|
*outdir = ClassifyRegion(edge_n_out, surf_n_out, surf_n);
|
||||||
|
@ -1038,35 +1038,31 @@ void SShell::MakeFromTransformationOf(SShell *a,
|
|||||||
{
|
{
|
||||||
booleanFailed = false;
|
booleanFailed = false;
|
||||||
surface.ReserveMore(a->surface.n);
|
surface.ReserveMore(a->surface.n);
|
||||||
SSurface *s;
|
for(SSurface &s : a->surface) {
|
||||||
for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) {
|
|
||||||
SSurface n;
|
SSurface n;
|
||||||
n = SSurface::FromTransformationOf(s, t, q, scale, /*includingTrims=*/true);
|
n = SSurface::FromTransformationOf(&s, t, q, scale, /*includingTrims=*/true);
|
||||||
surface.Add(&n); // keeping the old ID
|
surface.Add(&n); // keeping the old ID
|
||||||
}
|
}
|
||||||
|
|
||||||
curve.ReserveMore(a->curve.n);
|
curve.ReserveMore(a->curve.n);
|
||||||
SCurve *c;
|
for(SCurve &c : a->curve) {
|
||||||
for(c = a->curve.First(); c; c = a->curve.NextAfter(c)) {
|
|
||||||
SCurve n;
|
SCurve n;
|
||||||
n = SCurve::FromTransformationOf(c, t, q, scale);
|
n = SCurve::FromTransformationOf(&c, t, q, scale);
|
||||||
curve.Add(&n); // keeping the old ID
|
curve.Add(&n); // keeping the old ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShell::MakeEdgesInto(SEdgeList *sel) {
|
void SShell::MakeEdgesInto(SEdgeList *sel) {
|
||||||
SSurface *s;
|
for(SSurface &s : surface) {
|
||||||
for(s = surface.First(); s; s = surface.NextAfter(s)) {
|
s.MakeEdgesInto(this, sel, SSurface::MakeAs::XYZ);
|
||||||
s->MakeEdgesInto(this, sel, SSurface::MakeAs::XYZ);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SShell::MakeSectionEdgesInto(Vector n, double d, SEdgeList *sel, SBezierList *sbl)
|
void SShell::MakeSectionEdgesInto(Vector n, double d, SEdgeList *sel, SBezierList *sbl)
|
||||||
{
|
{
|
||||||
SSurface *s;
|
for(SSurface &s : surface) {
|
||||||
for(s = surface.First(); s; s = surface.NextAfter(s)) {
|
if(s.CoincidentWithPlane(n, d)) {
|
||||||
if(s->CoincidentWithPlane(n, d)) {
|
s.MakeSectionEdgesInto(this, sel, sbl);
|
||||||
s->MakeSectionEdgesInto(this, sel, sbl);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1088,15 +1084,13 @@ bool SShell::IsEmpty() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SShell::Clear() {
|
void SShell::Clear() {
|
||||||
SSurface *s;
|
for(SSurface &s : surface) {
|
||||||
for(s = surface.First(); s; s = surface.NextAfter(s)) {
|
s.Clear();
|
||||||
s->Clear();
|
|
||||||
}
|
}
|
||||||
surface.Clear();
|
surface.Clear();
|
||||||
|
|
||||||
SCurve *c;
|
for(SCurve &c : curve) {
|
||||||
for(c = curve.First(); c; c = curve.NextAfter(c)) {
|
c.Clear();
|
||||||
c->Clear();
|
|
||||||
}
|
}
|
||||||
curve.Clear();
|
curve.Clear();
|
||||||
}
|
}
|
||||||
|
@ -23,20 +23,20 @@ void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB,
|
|||||||
// Now we have to piecewise linearize the curve. If there's already an
|
// Now we have to piecewise linearize the curve. If there's already an
|
||||||
// identical curve in the shell, then follow that pwl exactly, otherwise
|
// identical curve in the shell, then follow that pwl exactly, otherwise
|
||||||
// calculate from scratch.
|
// calculate from scratch.
|
||||||
SCurve split, *existing = NULL, *se;
|
SCurve split, *existing = NULL;
|
||||||
SBezier sbrev = *sb;
|
SBezier sbrev = *sb;
|
||||||
sbrev.Reverse();
|
sbrev.Reverse();
|
||||||
bool backwards = false;
|
bool backwards = false;
|
||||||
#pragma omp critical(into)
|
#pragma omp critical(into)
|
||||||
{
|
{
|
||||||
for(se = into->curve.First(); se; se = into->curve.NextAfter(se)) {
|
for(SCurve &se : into->curve) {
|
||||||
if(se->isExact) {
|
if(se.isExact) {
|
||||||
if(sb->Equals(&(se->exact))) {
|
if(sb->Equals(&(se.exact))) {
|
||||||
existing = se;
|
existing = &se;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(sbrev.Equals(&(se->exact))) {
|
if(sbrev.Equals(&(se.exact))) {
|
||||||
existing = se;
|
existing = &se;
|
||||||
backwards = true;
|
backwards = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -332,15 +332,14 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB,
|
|||||||
shext = agnstA;
|
shext = agnstA;
|
||||||
}
|
}
|
||||||
bool foundExact = false;
|
bool foundExact = false;
|
||||||
SCurve *sc;
|
for(SCurve &sc : shext->curve) {
|
||||||
for(sc = shext->curve.First(); sc; sc = shext->curve.NextAfter(sc)) {
|
if(sc.source == SCurve::Source::INTERSECTION) continue;
|
||||||
if(sc->source == SCurve::Source::INTERSECTION) continue;
|
if(!sc.isExact) continue;
|
||||||
if(!sc->isExact) continue;
|
if((sc.surfA != sext->h) && (sc.surfB != sext->h)) continue;
|
||||||
if((sc->surfA != sext->h) && (sc->surfB != sext->h)) continue;
|
|
||||||
// we have a curve belonging to the curved surface and not the plane.
|
// we have a curve belonging to the curved surface and not the plane.
|
||||||
// does it lie completely in the plane?
|
// does it lie completely in the plane?
|
||||||
if(splane->ContainsPlaneCurve(sc)) {
|
if(splane->ContainsPlaneCurve(&sc)) {
|
||||||
SBezier bezier = sc->exact;
|
SBezier bezier = sc.exact;
|
||||||
AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into);
|
AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into);
|
||||||
foundExact = true;
|
foundExact = true;
|
||||||
}
|
}
|
||||||
@ -571,10 +570,9 @@ bool SSurface::ContainsPlaneCurve(SCurve *sc) const {
|
|||||||
void SShell::MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
|
void SShell::MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal,
|
||||||
SEdgeList *el, SShell *useCurvesFrom)
|
SEdgeList *el, SShell *useCurvesFrom)
|
||||||
{
|
{
|
||||||
SSurface *ss;
|
for(SSurface &ss : surface) {
|
||||||
for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) {
|
if(proto->CoincidentWith(&ss, sameNormal)) {
|
||||||
if(proto->CoincidentWith(ss, sameNormal)) {
|
ss.MakeEdgesInto(this, el, SSurface::MakeAs::XYZ, useCurvesFrom);
|
||||||
ss->MakeEdgesInto(this, el, SSurface::MakeAs::XYZ, useCurvesFrom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,14 +470,13 @@ void TextWindow::ShowListOfStyles() {
|
|||||||
Printf(true, "%Ft color style-name");
|
Printf(true, "%Ft color style-name");
|
||||||
|
|
||||||
bool darkbg = false;
|
bool darkbg = false;
|
||||||
Style *s;
|
for(Style &s : SK.style) {
|
||||||
for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) {
|
|
||||||
Printf(false, "%Bp %Bz %Bp %Fl%Ll%f%D%s%E",
|
Printf(false, "%Bp %Bz %Bp %Fl%Ll%f%D%s%E",
|
||||||
darkbg ? 'd' : 'a',
|
darkbg ? 'd' : 'a',
|
||||||
&s->color,
|
&s.color,
|
||||||
darkbg ? 'd' : 'a',
|
darkbg ? 'd' : 'a',
|
||||||
ScreenShowStyleInfo, s->h.v,
|
ScreenShowStyleInfo, s.h.v,
|
||||||
s->DescriptionString().c_str());
|
s.DescriptionString().c_str());
|
||||||
|
|
||||||
darkbg = !darkbg;
|
darkbg = !darkbg;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user