From e8bc62e16232aff442d2f0f6d52ff37e0c79be92 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 6 Oct 2012 18:28:38 +0000 Subject: Avoid unecessary minimizer calculations in dualcon * The minimize() function, which solves a least-squares problem, is only needed for sharp remesh mode, but was being calculated for smooth and blocks modes as well. Disabling this calculation when it's not needed gives a big performance boost. --- intern/dualcon/intern/octree.cpp | 78 ++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 19 deletions(-) (limited to 'intern') diff --git a/intern/dualcon/intern/octree.cpp b/intern/dualcon/intern/octree.cpp index f17148799a1..49c50c8240d 100644 --- a/intern/dualcon/intern/octree.cpp +++ b/intern/dualcon/intern/octree.cpp @@ -2128,8 +2128,32 @@ static void solve_least_squares(const float halfA[], const float b[], rvalue[i] = result(i); } +static void mass_point(float mp[3], const float pts[12][3], const int parity[12]) +{ + int ec = 0; + + for (int i = 0; i < 12; i++) { + if (parity[i]) { + const float *p = pts[i]; + + mp[0] += p[0]; + mp[1] += p[1]; + mp[2] += p[2]; + + ec++; + } + } + + if (ec == 0) { + return; + } + mp[0] /= ec; + mp[1] /= ec; + mp[2] /= ec; +} + static void minimize(float rvalue[3], float mp[3], const float pts[12][3], - const float norms[12][3], const int parity[12]) + const float norms[12][3], const int parity[12]) { float ata[6] = {0, 0, 0, 0, 0, 0}; float atb[3] = {0, 0, 0}; @@ -2183,27 +2207,43 @@ void Octree::computeMinimizer(const LeafNode *leaf, int st[3], int len, int parity[12]; fillEdgeIntersections(leaf, st, len, pts, norms, parity); - // Next, construct QEF and minimizer - float mp[3] = {0, 0, 0}; - minimize(rvalue, mp, pts, norms, parity); - - /* Restraining the location of the minimizer */ - float nh1 = hermite_num * len; - float nh2 = (1 + hermite_num) * len; - if ((mode == DUALCON_MASS_POINT || mode == DUALCON_CENTROID) || - (rvalue[0] < st[0] - nh1 || rvalue[1] < st[1] - nh1 || rvalue[2] < st[2] - nh1 || - rvalue[0] > st[0] + nh2 || rvalue[1] > st[1] + nh2 || rvalue[2] > st[2] + nh2)) { - if (mode == DUALCON_CENTROID) { - // Use centroids + switch (mode) { + case DUALCON_CENTROID: rvalue[0] = (float) st[0] + len / 2; rvalue[1] = (float) st[1] + len / 2; rvalue[2] = (float) st[2] + len / 2; - } - else { - // Use mass point instead - rvalue[0] = mp[0]; - rvalue[1] = mp[1]; - rvalue[2] = mp[2]; + break; + + case DUALCON_MASS_POINT: + rvalue[0] = rvalue[1] = rvalue[2] = 0; + mass_point(rvalue, pts, parity); + break; + + default: { + // Sharp features */ + + // construct QEF and minimizer + float mp[3] = {0, 0, 0}; + minimize(rvalue, mp, pts, norms, parity); + + /* Restraining the location of the minimizer */ + float nh1 = hermite_num * len; + float nh2 = (1 + hermite_num) * len; + + if (rvalue[0] < st[0] - nh1 || + rvalue[1] < st[1] - nh1 || + rvalue[2] < st[2] - nh1 || + + rvalue[0] > st[0] + nh2 || + rvalue[1] > st[1] + nh2 || + rvalue[2] > st[2] + nh2) + { + // Use mass point instead + rvalue[0] = mp[0]; + rvalue[1] = mp[1]; + rvalue[2] = mp[2]; + } + break; } } } -- cgit v1.2.3