Loading GUI/pom.xml +5 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,11 @@ <artifactId>MeshAlgorithms</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>LandmarksAlgorithms</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>javax.vecmath</groupId> <artifactId>vecmath</artifactId> Loading GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/BatchOctreeTestsMultipleFaces.java +6 −5 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.avgmesh.AvgMeshConstructorOctree; import cz.fidentis.analyst.avgmesh.AvgMeshConfig; import cz.fidentis.analyst.avgmesh.AvgMeshVisitor; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.face.HumanFaceFactory; import cz.fidentis.analyst.gui.task.batch.Stopwatch; import cz.fidentis.analyst.mesh.MeshIO; import cz.fidentis.analyst.registration.RegistrationUtils; import cz.fidentis.analyst.sampling.RandomSampling; import cz.fidentis.analyst.sampling.PointSamplingConfig; import java.io.File; import java.io.IOException; Loading Loading @@ -65,7 +66,7 @@ public class BatchOctreeTestsMultipleFaces { HumanFace initFace = factory.getFace(initFaceId); LOAD_TIME.stop(); AvgMeshConstructorOctree avgFaceConstructorOctree = null; AvgMeshVisitor avgFaceConstructorOctree = null; for (int i = 0; i < faces.size(); i++) { Loading @@ -85,7 +86,7 @@ public class BatchOctreeTestsMultipleFaces { 100, // max iterations false, 0.3, // error new RandomSampling(undersampling), new PointSamplingConfig(PointSamplingConfig.Method.RANDOM, undersampling), false, // drop k-d tree, if exists 1 // crop partially overlaid parts since the second iteration ); Loading @@ -99,7 +100,7 @@ public class BatchOctreeTestsMultipleFaces { AVG_FACE_COMPUTATION_TIME.start(); if (avgFaceConstructorOctree == null) { avgFaceConstructorOctree = new AvgMeshConstructorOctree(initFace.getMeshModel(), false); avgFaceConstructorOctree = (new AvgMeshConfig(initFace.getMeshModel())).getRayCastingVisitor(); } face.getOctree().accept(avgFaceConstructorOctree); AVG_FACE_COMPUTATION_TIME.stop(); Loading GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/BatchOctreeTestsTwoFaces.java +3 −2 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.avgmesh.AvgMeshConstructorOctree; import cz.fidentis.analyst.avgmesh.AvgMeshConfig; import cz.fidentis.analyst.avgmesh.AvgMeshVisitor; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.face.HumanFaceFactory; import cz.fidentis.analyst.gui.task.batch.Stopwatch; Loading Loading @@ -80,7 +81,7 @@ public class BatchOctreeTestsTwoFaces { OCTREE_CONSTRUCTION_TIME.stop(); AVG_FACE_COMPUTATION_TIME.start(); AvgMeshConstructorOctree avgFaceConstructorOctree = new AvgMeshConstructorOctree(mainFace.getMeshModel(), false); AvgMeshVisitor avgFaceConstructorOctree = (new AvgMeshConfig(mainFace.getMeshModel())).getRayCastingVisitor(); avgFaceConstructorOctree.visitOctree(secondFace.getOctree()); AVG_FACE_COMPUTATION_TIME.stop(); Loading GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/BatchSimilarityGroundTruth.java +19 −21 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.distance.MeshDistanceServices; import cz.fidentis.analyst.distance.MeshDistanceConfig; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.registration.RegistrationUtils; import cz.fidentis.analyst.distance.surface2surface.MeshDistanceNN; import cz.fidentis.analyst.sampling.NoSampling; import cz.fidentis.analyst.sampling.PointSamplingConfig; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; Loading Loading @@ -140,7 +142,7 @@ public class BatchSimilarityGroundTruth { 100, // max iterations false,// scale 0.05, // error new NoSampling(), // no undersampling new PointSamplingConfig(PointSamplingConfig.Method.NO_SAMPLING, 0), false, // drop k-d tree, if exists CROP_ICP // crop partially overlaid parts ); Loading @@ -150,26 +152,22 @@ public class BatchSimilarityGroundTruth { //long hdTime = System.currentTimeMillis(); // compute HD from secondary to primary: MeshDistanceNN hd = new MeshDistanceNN( distances[j][i] = MeshDistanceServices.measure( trFace.getMeshModel(), new MeshDistanceConfig( MeshDistanceConfig.Method.POINT_TO_POINT_NEAREST_NEIGHBORS, priFace.getKdTree(), MeshDistanceNN.Strategy.POINT_TO_TRIANGLE_APPROXIMATE, false, // relative distance true, // parallel CROP_DIST_MEASUREMENT // crop ); trFace.getMeshModel().compute(hd); distances[j][i] = hd.getDistancesOfVisitedFacets().getDistanceStats().getAverage(); false, CROP_DIST_MEASUREMENT)).getDistanceStats().getAverage(); // compute HD from primary to secondary: hd = new MeshDistanceNN( distances[i][j] = MeshDistanceServices.measure( priFace.getMeshModel(), new MeshDistanceConfig( MeshDistanceConfig.Method.POINT_TO_POINT_NEAREST_NEIGHBORS, trFace.getKdTree(), MeshDistanceNN.Strategy.POINT_TO_TRIANGLE_APPROXIMATE, false, // relative distance true, // parallel CROP_DIST_MEASUREMENT // crop ); priFace.getMeshModel().compute(hd); distances[i][j] = hd.getDistancesOfVisitedFacets().getDistanceStats().getAverage(); false, CROP_DIST_MEASUREMENT)).getDistanceStats().getAverage(); //hdComputationTime += System.currentTimeMillis() - hdTime; } Loading GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/IcpDownsampling.java +17 −52 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.distance.surface2surface.MeshDistanceNN; import cz.fidentis.analyst.distance.MeshDistanceServices; import cz.fidentis.analyst.distance.MeshDistanceConfig; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.gui.task.batch.Stopwatch; import cz.fidentis.analyst.mesh.MeshFacet; import cz.fidentis.analyst.mesh.MeshFactory; import cz.fidentis.analyst.mesh.MeshModel; import cz.fidentis.analyst.mesh.MeshTriangle; import cz.fidentis.analyst.registration.RegistrationUtils; import cz.fidentis.analyst.sampling.*; import cz.fidentis.analyst.sampling.PointSamplingConfig; import java.io.File; import java.io.IOException; Loading @@ -16,8 +15,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import static cz.fidentis.analyst.distance.surface2surface.MeshDistanceNN.Strategy.POINT_TO_TRIANGLE_APPROXIMATE; /** * This class evaluates efficiency (time) and precision of the ICP registration if different * sub-sampling algorithms with different strength are used. Loading @@ -33,7 +30,7 @@ public class IcpDownsampling { /** * Sub-sampling strategy */ private static final Strategy STRATEGY = Strategy.POISSON; private static final PointSamplingConfig.Method STRATEGY = PointSamplingConfig.Method.POISSON; /** * Surface smoothing strategy for the Poisson disk sampling Loading Loading @@ -72,19 +69,10 @@ public class IcpDownsampling { private static final boolean REGISTRATION_SCALE = false; private static final int REGISTRATION_IGNORE_PARTIALLY_OVERLAID_PARTS = 1; private static final MeshDistanceNN.Strategy SIMILARITY_STRATEGY = POINT_TO_TRIANGLE_APPROXIMATE; private static final MeshDistanceConfig.Method SIMILARITY_STRATEGY = MeshDistanceConfig.Method.POINT_TO_POINT_NEAREST_NEIGHBORS; private static final boolean SIMILARITY_RELATIVE_DISTANCE = false; private static final boolean SIMILARITY_AUTO_CROP = true; /** * Sub-sampling strategies. * * @author Radek Oslejsek */ private enum Strategy { RANDOM, GAUSSIAN, UNIFORM_SPACE, UNIFORM_MESH, POISSON } private static String veryDifferentFaces = ""; /** Loading Loading @@ -162,21 +150,9 @@ public class IcpDownsampling { MeshFactory.cloneMeshModel(secFaceFromFile.getMeshModel()), secFaceFromFile.getId()); PointSampling secSampling; if (numSamples == 0) { // skip sub-sampling, use full resolution secSampling = new NoSampling(); } else { switch (STRATEGY) { case RANDOM -> secSampling = new RandomSampling(numSamples); case GAUSSIAN -> secSampling = new CurvatureSampling(CurvatureSampling.CurvatureAlg.GAUSSIAN, numSamples); case UNIFORM_SPACE -> secSampling = new UniformSpaceSampling(numSamples); case UNIFORM_MESH -> secSampling = new UniformSurfaceSampling(numSamples); case POISSON -> secSampling = new PoissonDiskSubSampling(numSamples, SMOOTHING); default -> { return; } } } PointSamplingConfig secSampling = (numSamples == 0) // skip sub-sampling, use full resolution ? new PointSamplingConfig(PointSamplingConfig.Method.NO_SAMPLING, 0) : new PointSamplingConfig(STRATEGY, numSamples, SMOOTHING); efficiency.computeIfAbsent(numSamples, k-> new Stopwatch("")).start(); RegistrationUtils.alignMeshes( Loading @@ -192,16 +168,14 @@ public class IcpDownsampling { efficiency.get(numSamples).stop(); System.out.println("Second face: " + secSampling); MeshDistanceNN hd = new MeshDistanceNN( priFace.getKdTree(), double dist = MeshDistanceServices.measure( secFace.getMeshModel(), new MeshDistanceConfig( SIMILARITY_STRATEGY, priFace.getKdTree(), SIMILARITY_RELATIVE_DISTANCE, true, SIMILARITY_AUTO_CROP ); secFace.getMeshModel().compute(hd); double dist = hd.getDistancesOfVisitedFacets().getDistanceStats().getAverage(); )).getDistanceStats().getAverage(); precision.computeIfAbsent(numSamples, k -> new ArrayList<>()).add(dist); if (numSamples > 0) { // best achieved similarity with sub-sampling in action Loading @@ -216,13 +190,4 @@ public class IcpDownsampling { System.out.println(); } private static HumanFace downsamplePriFace(HumanFace priFace, PointSampling sampling) { sampling.visitMeshFacet(priFace.getMeshModel().getFacets().get(0)); MeshFacet reducedFacet = MeshFactory.createPointCloudFacet(sampling.getSamples()); MeshModel model = MeshFactory.createEmptyMeshModel(); model.setFacets(List.of(reducedFacet)); HumanFace ret = new HumanFace(model, priFace.getId()); return ret; } } Loading
GUI/pom.xml +5 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,11 @@ <artifactId>MeshAlgorithms</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>LandmarksAlgorithms</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>javax.vecmath</groupId> <artifactId>vecmath</artifactId> Loading
GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/BatchOctreeTestsMultipleFaces.java +6 −5 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.avgmesh.AvgMeshConstructorOctree; import cz.fidentis.analyst.avgmesh.AvgMeshConfig; import cz.fidentis.analyst.avgmesh.AvgMeshVisitor; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.face.HumanFaceFactory; import cz.fidentis.analyst.gui.task.batch.Stopwatch; import cz.fidentis.analyst.mesh.MeshIO; import cz.fidentis.analyst.registration.RegistrationUtils; import cz.fidentis.analyst.sampling.RandomSampling; import cz.fidentis.analyst.sampling.PointSamplingConfig; import java.io.File; import java.io.IOException; Loading Loading @@ -65,7 +66,7 @@ public class BatchOctreeTestsMultipleFaces { HumanFace initFace = factory.getFace(initFaceId); LOAD_TIME.stop(); AvgMeshConstructorOctree avgFaceConstructorOctree = null; AvgMeshVisitor avgFaceConstructorOctree = null; for (int i = 0; i < faces.size(); i++) { Loading @@ -85,7 +86,7 @@ public class BatchOctreeTestsMultipleFaces { 100, // max iterations false, 0.3, // error new RandomSampling(undersampling), new PointSamplingConfig(PointSamplingConfig.Method.RANDOM, undersampling), false, // drop k-d tree, if exists 1 // crop partially overlaid parts since the second iteration ); Loading @@ -99,7 +100,7 @@ public class BatchOctreeTestsMultipleFaces { AVG_FACE_COMPUTATION_TIME.start(); if (avgFaceConstructorOctree == null) { avgFaceConstructorOctree = new AvgMeshConstructorOctree(initFace.getMeshModel(), false); avgFaceConstructorOctree = (new AvgMeshConfig(initFace.getMeshModel())).getRayCastingVisitor(); } face.getOctree().accept(avgFaceConstructorOctree); AVG_FACE_COMPUTATION_TIME.stop(); Loading
GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/BatchOctreeTestsTwoFaces.java +3 −2 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.avgmesh.AvgMeshConstructorOctree; import cz.fidentis.analyst.avgmesh.AvgMeshConfig; import cz.fidentis.analyst.avgmesh.AvgMeshVisitor; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.face.HumanFaceFactory; import cz.fidentis.analyst.gui.task.batch.Stopwatch; Loading Loading @@ -80,7 +81,7 @@ public class BatchOctreeTestsTwoFaces { OCTREE_CONSTRUCTION_TIME.stop(); AVG_FACE_COMPUTATION_TIME.start(); AvgMeshConstructorOctree avgFaceConstructorOctree = new AvgMeshConstructorOctree(mainFace.getMeshModel(), false); AvgMeshVisitor avgFaceConstructorOctree = (new AvgMeshConfig(mainFace.getMeshModel())).getRayCastingVisitor(); avgFaceConstructorOctree.visitOctree(secondFace.getOctree()); AVG_FACE_COMPUTATION_TIME.stop(); Loading
GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/BatchSimilarityGroundTruth.java +19 −21 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.distance.MeshDistanceServices; import cz.fidentis.analyst.distance.MeshDistanceConfig; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.registration.RegistrationUtils; import cz.fidentis.analyst.distance.surface2surface.MeshDistanceNN; import cz.fidentis.analyst.sampling.NoSampling; import cz.fidentis.analyst.sampling.PointSamplingConfig; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; Loading Loading @@ -140,7 +142,7 @@ public class BatchSimilarityGroundTruth { 100, // max iterations false,// scale 0.05, // error new NoSampling(), // no undersampling new PointSamplingConfig(PointSamplingConfig.Method.NO_SAMPLING, 0), false, // drop k-d tree, if exists CROP_ICP // crop partially overlaid parts ); Loading @@ -150,26 +152,22 @@ public class BatchSimilarityGroundTruth { //long hdTime = System.currentTimeMillis(); // compute HD from secondary to primary: MeshDistanceNN hd = new MeshDistanceNN( distances[j][i] = MeshDistanceServices.measure( trFace.getMeshModel(), new MeshDistanceConfig( MeshDistanceConfig.Method.POINT_TO_POINT_NEAREST_NEIGHBORS, priFace.getKdTree(), MeshDistanceNN.Strategy.POINT_TO_TRIANGLE_APPROXIMATE, false, // relative distance true, // parallel CROP_DIST_MEASUREMENT // crop ); trFace.getMeshModel().compute(hd); distances[j][i] = hd.getDistancesOfVisitedFacets().getDistanceStats().getAverage(); false, CROP_DIST_MEASUREMENT)).getDistanceStats().getAverage(); // compute HD from primary to secondary: hd = new MeshDistanceNN( distances[i][j] = MeshDistanceServices.measure( priFace.getMeshModel(), new MeshDistanceConfig( MeshDistanceConfig.Method.POINT_TO_POINT_NEAREST_NEIGHBORS, trFace.getKdTree(), MeshDistanceNN.Strategy.POINT_TO_TRIANGLE_APPROXIMATE, false, // relative distance true, // parallel CROP_DIST_MEASUREMENT // crop ); priFace.getMeshModel().compute(hd); distances[i][j] = hd.getDistancesOfVisitedFacets().getDistanceStats().getAverage(); false, CROP_DIST_MEASUREMENT)).getDistanceStats().getAverage(); //hdComputationTime += System.currentTimeMillis() - hdTime; } Loading
GUI/src/main/java/cz/fidentis/analyst/gui/app/tools/IcpDownsampling.java +17 −52 Original line number Diff line number Diff line package cz.fidentis.analyst.gui.app.tools; import cz.fidentis.analyst.distance.surface2surface.MeshDistanceNN; import cz.fidentis.analyst.distance.MeshDistanceServices; import cz.fidentis.analyst.distance.MeshDistanceConfig; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.gui.task.batch.Stopwatch; import cz.fidentis.analyst.mesh.MeshFacet; import cz.fidentis.analyst.mesh.MeshFactory; import cz.fidentis.analyst.mesh.MeshModel; import cz.fidentis.analyst.mesh.MeshTriangle; import cz.fidentis.analyst.registration.RegistrationUtils; import cz.fidentis.analyst.sampling.*; import cz.fidentis.analyst.sampling.PointSamplingConfig; import java.io.File; import java.io.IOException; Loading @@ -16,8 +15,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import static cz.fidentis.analyst.distance.surface2surface.MeshDistanceNN.Strategy.POINT_TO_TRIANGLE_APPROXIMATE; /** * This class evaluates efficiency (time) and precision of the ICP registration if different * sub-sampling algorithms with different strength are used. Loading @@ -33,7 +30,7 @@ public class IcpDownsampling { /** * Sub-sampling strategy */ private static final Strategy STRATEGY = Strategy.POISSON; private static final PointSamplingConfig.Method STRATEGY = PointSamplingConfig.Method.POISSON; /** * Surface smoothing strategy for the Poisson disk sampling Loading Loading @@ -72,19 +69,10 @@ public class IcpDownsampling { private static final boolean REGISTRATION_SCALE = false; private static final int REGISTRATION_IGNORE_PARTIALLY_OVERLAID_PARTS = 1; private static final MeshDistanceNN.Strategy SIMILARITY_STRATEGY = POINT_TO_TRIANGLE_APPROXIMATE; private static final MeshDistanceConfig.Method SIMILARITY_STRATEGY = MeshDistanceConfig.Method.POINT_TO_POINT_NEAREST_NEIGHBORS; private static final boolean SIMILARITY_RELATIVE_DISTANCE = false; private static final boolean SIMILARITY_AUTO_CROP = true; /** * Sub-sampling strategies. * * @author Radek Oslejsek */ private enum Strategy { RANDOM, GAUSSIAN, UNIFORM_SPACE, UNIFORM_MESH, POISSON } private static String veryDifferentFaces = ""; /** Loading Loading @@ -162,21 +150,9 @@ public class IcpDownsampling { MeshFactory.cloneMeshModel(secFaceFromFile.getMeshModel()), secFaceFromFile.getId()); PointSampling secSampling; if (numSamples == 0) { // skip sub-sampling, use full resolution secSampling = new NoSampling(); } else { switch (STRATEGY) { case RANDOM -> secSampling = new RandomSampling(numSamples); case GAUSSIAN -> secSampling = new CurvatureSampling(CurvatureSampling.CurvatureAlg.GAUSSIAN, numSamples); case UNIFORM_SPACE -> secSampling = new UniformSpaceSampling(numSamples); case UNIFORM_MESH -> secSampling = new UniformSurfaceSampling(numSamples); case POISSON -> secSampling = new PoissonDiskSubSampling(numSamples, SMOOTHING); default -> { return; } } } PointSamplingConfig secSampling = (numSamples == 0) // skip sub-sampling, use full resolution ? new PointSamplingConfig(PointSamplingConfig.Method.NO_SAMPLING, 0) : new PointSamplingConfig(STRATEGY, numSamples, SMOOTHING); efficiency.computeIfAbsent(numSamples, k-> new Stopwatch("")).start(); RegistrationUtils.alignMeshes( Loading @@ -192,16 +168,14 @@ public class IcpDownsampling { efficiency.get(numSamples).stop(); System.out.println("Second face: " + secSampling); MeshDistanceNN hd = new MeshDistanceNN( priFace.getKdTree(), double dist = MeshDistanceServices.measure( secFace.getMeshModel(), new MeshDistanceConfig( SIMILARITY_STRATEGY, priFace.getKdTree(), SIMILARITY_RELATIVE_DISTANCE, true, SIMILARITY_AUTO_CROP ); secFace.getMeshModel().compute(hd); double dist = hd.getDistancesOfVisitedFacets().getDistanceStats().getAverage(); )).getDistanceStats().getAverage(); precision.computeIfAbsent(numSamples, k -> new ArrayList<>()).add(dist); if (numSamples > 0) { // best achieved similarity with sub-sampling in action Loading @@ -216,13 +190,4 @@ public class IcpDownsampling { System.out.println(); } private static HumanFace downsamplePriFace(HumanFace priFace, PointSampling sampling) { sampling.visitMeshFacet(priFace.getMeshModel().getFacets().get(0)); MeshFacet reducedFacet = MeshFactory.createPointCloudFacet(sampling.getSamples()); MeshModel model = MeshFactory.createEmptyMeshModel(); model.setFacets(List.of(reducedFacet)); HumanFace ret = new HumanFace(model, priFace.getId()); return ret; } }