Skip to content
Snippets Groups Projects
Commit f2dd42c4 authored by Radek Ošlejšek's avatar Radek Ošlejšek
Browse files

Singnificantly improved efficiency by caching re-used data

parent e3a9d6b2
No related branches found
No related tags found
No related merge requests found
...@@ -47,47 +47,31 @@ public class ApproxSymmetryPlane extends Plane implements Comparable<ApproxSymme ...@@ -47,47 +47,31 @@ public class ApproxSymmetryPlane extends Plane implements Comparable<ApproxSymme
} }
private void setNormAndDist(MeshFacet facet, SignificantPoints sigPoints, Config config, int i, int j) { private void setNormAndDist(MeshFacet facet, SignificantPoints sigPoints, Config config, int i, int j) {
double sigCurvI = sigPoints.getCurvature(i);
double sigCurvJ = sigPoints.getCurvature(j);
int sigPointI = sigPoints.getVertexIndex(i); int sigPointI = sigPoints.getVertexIndex(i);
int sigPointJ = sigPoints.getVertexIndex(j); int sigPointJ = sigPoints.getVertexIndex(j);
MeshPoint meshPointI = facet.getVertex(sigPointI);
MeshPoint meshPointJ = facet.getVertex(sigPointJ);
double minRatio = config.getMinCurvRatio(); double minRatio = config.getMinCurvRatio();
double maxRatio = 1.0 / minRatio; double maxRatio = 1.0 / minRatio;
double ratioIJ = sigCurvI / sigCurvJ; double ratioIJ = sigPoints.getCachedCurRatio(i, j);
if (ratioIJ < minRatio || ratioIJ > maxRatio) { if (ratioIJ < minRatio || ratioIJ > maxRatio) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
MeshPoint meshPointI = facet.getVertex(sigPointI);
MeshPoint meshPointJ = facet.getVertex(sigPointJ);
Vector3d p1 = new Vector3d(meshPointI.getPosition()); Vector3d p1 = new Vector3d(meshPointI.getPosition());
Vector3d p2 = new Vector3d(meshPointJ.getPosition()); Vector3d p2 = new Vector3d(meshPointJ.getPosition());
Vector3d avrg = new Vector3d(p1);
avrg.add(p2);
avrg.scale(0.5);
Vector3d normal = new Vector3d(p1); Vector3d normal = new Vector3d(p1);
normal.sub(p2); normal.sub(p2);
normal.normalize(); normal.normalize();
double d = -(normal.x * avrg.x) - (normal.y * avrg.y) - (normal.z * avrg.z); double normCos = sigPoints.getCachedNormCosVec(i, j).dot(normal);
Vector3d ni = new Vector3d(meshPointI.getNormal());
Vector3d nj = new Vector3d(meshPointI.getNormal());
ni.normalize();
nj.normalize();
Vector3d normVec = new Vector3d(ni);
normVec.sub(nj);
normVec.normalize();
double normCos = normVec.dot(normal);
if (Math.abs(normCos) < config.getMinNormAngleCos()) { if (Math.abs(normCos) < config.getMinNormAngleCos()) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
Vector3d avrg = sigPoints.getCachedAvgPos(i, j);
double d = -(normal.x * avrg.x) - (normal.y * avrg.y) - (normal.z * avrg.z);
setNormal(normal); setNormal(normal);
setDistance(d); setDistance(d);
...@@ -102,9 +86,7 @@ public class ApproxSymmetryPlane extends Plane implements Comparable<ApproxSymme ...@@ -102,9 +86,7 @@ public class ApproxSymmetryPlane extends Plane implements Comparable<ApproxSymme
* @param maxDist Distance limit * @param maxDist Distance limit
*/ */
private void computeVotes(MeshFacet facet, SignificantPoints sigPoints, Config config, double maxDist) { private void computeVotes(MeshFacet facet, SignificantPoints sigPoints, Config config, double maxDist) {
normalize(); normalize();
Vector3d normal = getNormal(); Vector3d normal = getNormal();
double d = getDistance(); double d = getDistance();
double maxCurvRatio = 1.0 / config.getMinCurvRatio(); double maxCurvRatio = 1.0 / config.getMinCurvRatio();
...@@ -119,42 +101,32 @@ public class ApproxSymmetryPlane extends Plane implements Comparable<ApproxSymme ...@@ -119,42 +101,32 @@ public class ApproxSymmetryPlane extends Plane implements Comparable<ApproxSymme
continue; continue;
} }
double ratioIJ = sigPoints.getCurvature(i) / sigPoints.getCurvature(j); double ratioIJ = sigPoints.getCachedCurRatio(i, j);
if (ratioIJ < config.getMinCurvRatio() || ratioIJ > maxCurvRatio) { if (ratioIJ < config.getMinCurvRatio() || ratioIJ > maxCurvRatio) {
continue; continue;
} }
double normCos = sigPoints.getCachedNormCosVec(i, j).dot(normal);
if (Math.abs(normCos) < config.getMinNormAngleCos()) {
continue;
}
int sigPointI = sigPoints.getVertexIndex(i); int sigPointI = sigPoints.getVertexIndex(i);
int sigPointJ = sigPoints.getVertexIndex(j); int sigPointJ = sigPoints.getVertexIndex(j);
MeshPoint meshPointI = facet.getVertex(sigPointI);
MeshPoint meshPointJ = facet.getVertex(sigPointJ);
Vector3d vec = new Vector3d(facet.getVertices().get(sigPointI).getPosition()); Vector3d vec = new Vector3d(meshPointI.getPosition());
vec.sub(facet.getVertices().get(sigPointJ).getPosition()); vec.sub(meshPointJ.getPosition());
vec.normalize(); vec.normalize();
double cos = vec.dot(normal); double cos = vec.dot(normal);
if (Math.abs(cos) < config.getMinAngleCos()) {
Vector3d ni = new Vector3d(facet.getVertex(sigPointI).getNormal());
Vector3d nj = new Vector3d(facet.getVertex(sigPointJ).getNormal());
ni.normalize();
nj.normalize();
Vector3d normVec = ni;
normVec.sub(nj);
normVec.normalize();
double normCos = normVec.dot(normal);
if (Math.abs(cos) < config.getMinAngleCos() || Math.abs(normCos) < config.getMinNormAngleCos()) {
continue; continue;
} }
Vector3d avrg = new Vector3d(facet.getVertices().get(sigPointI).getPosition()); Vector3d avrg = sigPoints.getCachedAvgPos(i, j);
Vector3d aux = new Vector3d(facet.getVertices().get(sigPointJ).getPosition());
avrg.add(aux);
avrg.scale(0.5);
double dist = normal.x * avrg.x + normal.y * avrg.y + normal.z * avrg.z + d; double dist = normal.x * avrg.x + normal.y * avrg.y + normal.z * avrg.z + d;
dist = Math.abs(dist); dist = Math.abs(dist);
if (dist <= maxDist) { if (dist <= maxDist) {
votes++; votes++;
} }
......
package cz.fidentis.analyst.symmetry; package cz.fidentis.analyst.symmetry;
import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.mesh.core.MeshPoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.vecmath.Vector3d;
/** /**
* Finds and stores the top X points with the most significant curvarure. * Finds and stores the top X points with the most significant curvarure.
...@@ -12,7 +15,14 @@ import java.util.List; ...@@ -12,7 +15,14 @@ import java.util.List;
*/ */
public class SignificantPoints { public class SignificantPoints {
private List<VertCurvature> significantPoints; private final List<VertCurvature> significantPoints;
private List<List<Vector3d>> normCosVecCache;
private List<List<Vector3d>> avgPosCache;
private List<List<Double>> curRatioCache;
/** /**
* Constructor. * Constructor.
...@@ -20,15 +30,81 @@ public class SignificantPoints { ...@@ -20,15 +30,81 @@ public class SignificantPoints {
* @param max Maximal number of points * @param max Maximal number of points
*/ */
public SignificantPoints(List<Double> curvatures, int max) { public SignificantPoints(List<Double> curvatures, int max) {
significantPoints = new ArrayList<>(curvatures.size()); List<VertCurvature> sp = new ArrayList<>(curvatures.size());
for (int i = 0; i < curvatures.size(); i++) { for (int i = 0; i < curvatures.size(); i++) {
significantPoints.add(new VertCurvature(i, curvatures.get(i))); sp.add(new VertCurvature(i, curvatures.get(i)));
}
Collections.sort(sp);
if (max < sp.size()) {
significantPoints = new ArrayList<>(sp.subList(0, max));
} else {
significantPoints = sp;
}
}
public void cacheData(MeshFacet facet) {
if (normCosVecCache != null) {
return;
} }
Collections.sort(significantPoints); normCosVecCache = new ArrayList<>(significantPoints.size());
if (max < significantPoints.size()) { avgPosCache = new ArrayList<>(significantPoints.size());
significantPoints = new ArrayList<>(significantPoints.subList(0, max)); curRatioCache = new ArrayList<>(significantPoints.size());
for (int i = 0; i < significantPoints.size(); i++) {
List<Vector3d> cosArray = new ArrayList<>(significantPoints.size());
normCosVecCache.add(cosArray);
List<Vector3d> posArray = new ArrayList<>(significantPoints.size());
avgPosCache.add(posArray);
List<Double> curArray = new ArrayList<>(significantPoints.size());
curRatioCache.add(curArray);
for (int j = 0; j < significantPoints.size(); j++) {
MeshPoint meshPointI = facet.getVertex(significantPoints.get(i).vertIndex);
MeshPoint meshPointJ = facet.getVertex(significantPoints.get(j).vertIndex);
Vector3d ni = new Vector3d(meshPointI.getNormal());
Vector3d nj = new Vector3d(meshPointJ.getNormal());
ni.normalize();
nj.normalize();
ni.sub(nj);
ni.normalize();
cosArray.add(ni);
Vector3d avrg = new Vector3d(meshPointI.getPosition());
Vector3d aux = new Vector3d(meshPointJ.getPosition());
avrg.add(aux);
avrg.scale(0.5);
posArray.add(avrg);
curArray.add(significantPoints.get(i).curvature / significantPoints.get(j).curvature);
}
}
}
public Vector3d getCachedNormCosVec(int i, int j) {
if (normCosVecCache == null || i >= normCosVecCache.size() || i >= normCosVecCache.size() || i < 0 || j < 0) {
return null;
}
return normCosVecCache.get(i).get(j);
}
public Vector3d getCachedAvgPos(int i, int j) {
if (avgPosCache == null || i >= avgPosCache.size() || i >= avgPosCache.size() || i < 0 || j < 0) {
return null;
}
return avgPosCache.get(i).get(j);
}
public double getCachedCurRatio(int i, int j) {
if (curRatioCache == null || i >= curRatioCache.size() || i >= curRatioCache.size() || i < 0 || j < 0) {
return Double.NaN;
} }
return curRatioCache.get(i).get(j);
} }
/** /**
......
...@@ -90,6 +90,7 @@ public class SymmetryEstimator { ...@@ -90,6 +90,7 @@ public class SymmetryEstimator {
curvatures = calculateCurvatures(facet, maxCurvatureAlg); curvatures = calculateCurvatures(facet, maxCurvatureAlg);
final SignificantPoints sigPoints = new SignificantPoints(curvatures, config.getSignificantPointCount()); final SignificantPoints sigPoints = new SignificantPoints(curvatures, config.getSignificantPointCount());
sigPoints.cacheData(facet);
// Initiate structure for concurrent computation: // Initiate structure for concurrent computation:
ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment