Optimize FromTransformationOf for performing identity transformation.

FromTransformationOf is called with an identity rotation or
translation for translation and rotation groups, and for every
group that doesn't produce a solid model. This commit omits any
calculations from it when the relevant part of transformation
would change nothing.

This commit results in a ~10% improvement on testcase
woodworking/big-big-big-woodworking-asm, and splitting the condition
into three parts results in a ~5% improvement on testcase
stress/rotate_groups_0.
single-window
EvilSpirit 2016-11-10 22:07:13 +07:00 committed by whitequark
parent 0ae0343fc7
commit 683ac78ca2
2 changed files with 41 additions and 14 deletions

View File

@ -729,8 +729,11 @@ void SBezierLoopSetSet::Clear() {
SCurve SCurve::FromTransformationOf(SCurve *a, Vector t, SCurve SCurve::FromTransformationOf(SCurve *a, Vector t,
Quaternion q, double scale) Quaternion q, double scale)
{ {
SCurve ret = {}; bool needRotate = !EXACT(q.vx == 0.0 && q.vy == 0.0 && q.vz == 0.0 && q.w == 1.0);
bool needTranslate = !EXACT(t.x == 0.0 && t.y == 0.0 && t.z == 0.0);
bool needScale = !EXACT(scale == 1.0);
SCurve ret = {};
ret.h = a->h; ret.h = a->h;
ret.isExact = a->isExact; ret.isExact = a->isExact;
ret.exact = (a->exact).TransformedBy(t, q, scale); ret.exact = (a->exact).TransformedBy(t, q, scale);
@ -740,8 +743,15 @@ SCurve SCurve::FromTransformationOf(SCurve *a, Vector t,
SCurvePt *p; SCurvePt *p;
for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) { for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) {
SCurvePt pp = *p; SCurvePt pp = *p;
pp.p = (pp.p).ScaledBy(scale); if(needScale) {
pp.p = (q.Rotate(pp.p)).Plus(t); pp.p = (pp.p).ScaledBy(scale);
}
if(needRotate) {
pp.p = q.Rotate(pp.p);
}
if(needTranslate) {
pp.p = pp.p.Plus(t);
}
ret.pts.Add(&pp); ret.pts.Add(&pp);
} }
return ret; return ret;

View File

@ -131,12 +131,14 @@ SSurface SSurface::FromPlane(Vector pt, Vector u, Vector v) {
return ret; return ret;
} }
SSurface SSurface::FromTransformationOf(SSurface *a, SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q, double scale,
Vector t, Quaternion q, double scale,
bool includingTrims) bool includingTrims)
{ {
SSurface ret = {}; bool needRotate = !EXACT(q.vx == 0.0 && q.vy == 0.0 && q.vz == 0.0 && q.w == 1.0);
bool needTranslate = !EXACT(t.x == 0.0 && t.y == 0.0 && t.z == 0.0);
bool needScale = !EXACT(scale == 1.0);
SSurface ret = {};
ret.h = a->h; ret.h = a->h;
ret.color = a->color; ret.color = a->color;
ret.face = a->face; ret.face = a->face;
@ -146,10 +148,17 @@ SSurface SSurface::FromTransformationOf(SSurface *a,
int i, j; int i, j;
for(i = 0; i <= 3; i++) { for(i = 0; i <= 3; i++) {
for(j = 0; j <= 3; j++) { for(j = 0; j <= 3; j++) {
ret.ctrl[i][j] = a->ctrl[i][j]; Vector ctrl = a->ctrl[i][j];
ret.ctrl[i][j] = (ret.ctrl[i][j]).ScaledBy(scale); if(needScale) {
ret.ctrl[i][j] = (q.Rotate(ret.ctrl[i][j])).Plus(t); ctrl = ctrl.ScaledBy(scale);
}
if(needRotate) {
ctrl = q.Rotate(ctrl);
}
if(needTranslate) {
ctrl = ctrl.Plus(t);
}
ret.ctrl[i][j] = ctrl;
ret.weight[i][j] = a->weight[i][j]; ret.weight[i][j] = a->weight[i][j];
} }
} }
@ -158,10 +167,18 @@ SSurface SSurface::FromTransformationOf(SSurface *a,
STrimBy *stb; STrimBy *stb;
for(stb = a->trim.First(); stb; stb = a->trim.NextAfter(stb)) { for(stb = a->trim.First(); stb; stb = a->trim.NextAfter(stb)) {
STrimBy n = *stb; STrimBy n = *stb;
n.start = n.start.ScaledBy(scale); if(needScale) {
n.finish = n.finish.ScaledBy(scale); n.start = n.start.ScaledBy(scale);
n.start = (q.Rotate(n.start)) .Plus(t); n.finish = n.finish.ScaledBy(scale);
n.finish = (q.Rotate(n.finish)).Plus(t); }
if(needRotate) {
n.start = q.Rotate(n.start);
n.finish = q.Rotate(n.finish);
}
if(needTranslate) {
n.start = n.start.Plus(t);
n.finish = n.finish.Plus(t);
}
ret.trim.Add(&n); ret.trim.Add(&n);
} }
} }