diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java index 99020c3ce519f015c32eabd85c1377a0fc02ede8..f33514d3fe83f7e658aa8bf89ee31091921e6ea4 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/ClosestNodeMultipleVisitor.java @@ -74,7 +74,7 @@ public class ClosestNodeMultipleVisitor extends KdTreeVisitor { @Override - public Object clone() { + public KdTreeVisitor clone() { return new ClosestNodeMultipleVisitor(myPoint, concurrently()); } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceKdTreeVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceKdTreeVisitor.java index df36112903707dbb9035e3f8b1ae019af5f9b6f3..f700ef619400c3e3252cb2ff871682a5cf087f59 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceKdTreeVisitor.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceKdTreeVisitor.java @@ -109,7 +109,7 @@ public abstract class DistanceKdTreeVisitor extends KdTreeVisitor implements Nea } @Override - public abstract Object clone(); + public abstract KdTreeVisitor clone(); diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdTrianglesApprox.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdTrianglesApprox.java index 197f2b268de40bd60f7b7296cc5f1bbfc088979b..83af0ffdbf7874d98989bc71ae75048e6cb87915 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdTrianglesApprox.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdTrianglesApprox.java @@ -1,6 +1,7 @@ package cz.fidentis.analyst.visitors.kdtree; import cz.fidentis.analyst.kdtree.KdTree; +import cz.fidentis.analyst.kdtree.KdTreeVisitor; import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.mesh.core.MeshPoint; import cz.fidentis.analyst.mesh.core.MeshPointImpl; @@ -80,7 +81,7 @@ public class DistanceToKdTrianglesApprox extends DistanceKdTreeVisitor implement } @Override - public Object clone() { + public KdTreeVisitor clone() { return new DistanceToKdTrianglesApprox(this); } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdVertices.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdVertices.java index 83473feb40696ea0769bceeda799e7acef3e9679..8d237f8755649baceb7f3c403dc4ce86daf9942d 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdVertices.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/kdtree/DistanceToKdVertices.java @@ -2,6 +2,7 @@ package cz.fidentis.analyst.visitors.kdtree; import cz.fidentis.analyst.kdtree.KdNode; import cz.fidentis.analyst.kdtree.KdTree; +import cz.fidentis.analyst.kdtree.KdTreeVisitor; import cz.fidentis.analyst.mesh.core.MeshPoint; import cz.fidentis.analyst.mesh.core.MeshPointImpl; import java.util.ArrayList; @@ -65,7 +66,7 @@ public class DistanceToKdVertices extends DistanceKdTreeVisitor implements Neare } @Override - public Object clone() { + public KdTreeVisitor clone() { return new DistanceToKdVertices(this); } diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/DistanceMeshVisitor.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/DistanceMeshVisitor.java new file mode 100644 index 0000000000000000000000000000000000000000..68db884e3871ff4c1876bf30fb9f2cc1522d9415 --- /dev/null +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/DistanceMeshVisitor.java @@ -0,0 +1,172 @@ +package cz.fidentis.analyst.visitors.mesh; + +import cz.fidentis.analyst.mesh.MeshVisitor; +import cz.fidentis.analyst.mesh.core.MeshFacet; +import cz.fidentis.analyst.mesh.core.MeshPoint; +import cz.fidentis.analyst.mesh.core.MeshPointImpl; +import cz.fidentis.analyst.visitors.NearestMeshFacets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import javax.vecmath.Vector3d; + +/** + * A functor. When instantiated, it can be gradually applied to multiple mesh facets. + * It inspects the state of triangular meshes one by one, and (cumulatevely) computes results. + * <p> + * Implement this interface whenever you want to define new algorithm over a {@link MeshFacet}. + * </p> + * <p> + * The visitor can be instatiated either as sequential and concurrent. + * The {@link cz.fidentis.analyst.mesh.MeshVisitor#visit} inspection method + * of a sequential visitor is applied immediately. On the contrary, if the + * visitor is concurrent and thread-safe, then the method only stores the inpected + * mesh for later concurrent inspection. To trigger the mesh inspection, + * a {@link java.util.concurrent.ExecutorService} has to be used calling + * the {@link cz.fidentis.analyst.mesh.MeshVisitor#call} method asynchronously + * and then waiting for the results of all triggered visitors. + * </p> + * <p> + * All visitors have to be cloneable. A returned clone represents a visitor in + * the initial state, i.e., only the configuration options provided to the constructor + * are cloned while the computation state is set to initial values. + * </p> + * + * @author Radek Oslejsek + */ +public abstract class DistanceMeshVisitor extends MeshVisitor implements NearestMeshFacets { + + private final boolean relativeDist; + + /** + * A 3D point in space from which the distance is measured. + */ + private final MeshPoint point3d; + + private int sign = 1; + + /** + * The minimum distance found so far. + */ + private double distance = Double.POSITIVE_INFINITY; + + /** + * Mesh facets lying at the minimal distance + */ + private List<MeshFacet> closestFacets = new ArrayList<>(); + + /** + * Constructor. + * + * @param point A 3D point from which the distance is computed. Must not be {@code null} + * @param relativeDistance If {@true}, the visitor calculates the distances with respect + * to the normals of the 3D point (the normal has to be present), + * i.e., we can get negative distance. + * @param concurrently If {@code true} and this visitor is thread-safe, then + * the visitor is applied concurrently on multiple KD trees. + * @throws IllegalArgumentException if some parametr is wrong + */ + public DistanceMeshVisitor(MeshPoint point, boolean relativeDistance, boolean concurrently) { + super(concurrently); + if (point == null) { + throw new IllegalArgumentException("point"); + } + if (point.getNormal() == null && relativeDistance) { + throw new IllegalArgumentException("normal required for relative distance"); + } + this.point3d = point; + this.relativeDist = relativeDistance; + } + + /** + * Constructor. + * + * @param point A 3D point from which distance is computed. Must not be {@code null} + * @param concurrently If {@code true} and this visitor is thread-safe, then + * the visitor is applied concurrently on multiple KD trees. + * @throws IllegalArgumentException if some parametr is wrong + */ + public DistanceMeshVisitor(Vector3d point, boolean concurrently) { + this (new MeshPointImpl(point, null, null), false, concurrently); + } + + /** + * Copy constructor. + * + * @param vis source visitor to be coppied + * @throws NullPointerException if the input parameter is {@code null} + */ + protected DistanceMeshVisitor(DistanceMeshVisitor vis) { + super(vis); + this.point3d = vis.point3d; + this.relativeDist = vis.relativeDist; + } + + + @Override + public double getDistance() { + return relativeDist ? sign * distance : distance; + } + + @Override + public boolean relativeDistance() { + return relativeDist; + } + + @Override + public List<MeshFacet> getClosestFacets() { + return Collections.unmodifiableList(closestFacets); + } + + @Override + public abstract MeshVisitor clone(); + + + + + protected MeshPoint getPoint3d() { + return point3d; + } + + /** + * @return -1 if the distance is migger (no update), 0 the same , 1 smaller + */ + protected synchronized int checkAndUpdateFacets(double dist, int sign, Collection<MeshFacet> facets) { + if (dist > distance) { + return -1; + } + + if (dist < distance) { + distance = dist; + this.sign = sign; + closestFacets.clear(); + closestFacets.addAll(facets); + return 1; + } else { // the same distance + closestFacets.addAll(facets); + return 0; + } + } + + /** + * @return -1 if the distance is migger (no update), 0 the same , 1 smaller + */ + protected synchronized int checkAndUpdateFacet(double dist, int sign, MeshFacet facet) { + if (dist > distance) { + return -1; + } + + if (dist < distance) { + distance = dist; + this.sign = sign; + closestFacets.clear(); + closestFacets.add(facet); + return 1; + } else { // the same distance + closestFacets.add(facet); + return 0; + } + } + +} diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/kdtree/KdTreeVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/kdtree/KdTreeVisitor.java index 12d2308c8c5e553e1c6e9704d0b6884ed2af4973..26a6ecd83dc11b1882ab5d7fc7b2e6b54c2ba190 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/kdtree/KdTreeVisitor.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/kdtree/KdTreeVisitor.java @@ -15,7 +15,7 @@ import java.util.concurrent.Callable; * visitor is concurrent and thread-safe, then the method only stores the inpected * k-d tree for later concurrent inspection. To trigger the tree inspection, * a {@link java.util.concurrent.ExecutorService} has to be used calling - * the {@link cz.fidentis.analyst.mesh.mesh.MeshVisitor#call} method asynchronously + * the {@link cz.fidentis.analyst.kdtree.KdTreeVisitor#call} method asynchronously * and then waiting for the results of all triggered visitors. * </p> * <p> @@ -124,5 +124,5 @@ public abstract class KdTreeVisitor implements Callable<KdTreeVisitor>, Cloneabl * @return a copy of this visitor */ @Override - public abstract Object clone(); + public abstract KdTreeVisitor clone(); } diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java index 11ac8a470d17a06e9ea4170fc119d21f14e418af..88c6a15eea3ab7ee5795020543c39baf06932c93 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/MeshVisitor.java @@ -52,6 +52,16 @@ public abstract class MeshVisitor implements Callable<MeshVisitor>, Cloneable { this.concurrently = concurrently; } + /** + * Copy constructor. + * + * @param vis source visitor to be coppied + * @throws NullPointerException if the input parameter is {@code null} + */ + protected MeshVisitor(MeshVisitor vis) { + concurrently = vis.concurrently; + } + /** * Returns {@code true} if the implementation is thread-safe and then * <b>a single visitor instance</b> can be applied to multiple mesh facets simultaneously.