Loading Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java +16 −38 Original line number Diff line number Diff line package cz.fidentis.analyst.face; import cz.fidentis.analyst.face.events.HumanFaceListener; import com.google.common.eventbus.EventBus; import cz.fidentis.analyst.face.events.HumanFaceEvent; import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.services.FeaturePointImportService; import cz.fidentis.analyst.kdtree.KdTree; import cz.fidentis.analyst.kdtree.events.KdTreeCreated; import cz.fidentis.analyst.kdtree.events.KdTreeDestroyed; import cz.fidentis.analyst.kdtree.events.KdTreeEvent; import cz.fidentis.analyst.face.events.KdTreeCreated; import cz.fidentis.analyst.face.events.KdTreeDestroyed; import cz.fidentis.analyst.face.events.MeshChangedEvent; import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.mesh.core.MeshModel; import cz.fidentis.analyst.mesh.events.MeshEvent; import cz.fidentis.analyst.mesh.events.MeshListener; import cz.fidentis.analyst.kdtree.events.KdTreeListener; import cz.fidentis.analyst.mesh.io.MeshObjLoader; import cz.fidentis.analyst.symmetry.Plane; import cz.fidentis.analyst.visitors.face.HumanFaceVisitor; Loading Loading @@ -43,18 +42,10 @@ import java.util.Objects; * Then they are informed about changes in the human automatically via methods * prescribed by the interface. * </p> * <p> * Events fired by the class: * <ul> * <li>{@link cz.fidentis.analyst.mesh.events.MeshEvent} or its sub-type if * the mesh model changes (see {@link cz.fidentis.analyst.mesh.core.MeshModel} * documentation for monitored changes).</li> * </ul> * </p> * * @author Radek Oslejsek */ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public class HumanFace implements Serializable { private MeshModel meshModel; Loading Loading @@ -87,7 +78,6 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public HumanFace(File file) throws IOException { meshModel = MeshObjLoader.read(new FileInputStream(file)); meshModel.simplifyModel(); meshModel.registerListener(this); this.id = file.getCanonicalPath(); } Loading @@ -110,7 +100,7 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { throw new IllegalArgumentException("meshModel"); } this.meshModel = meshModel; //eventBus.post(new MeshChangedEvent()); eventBus.post(new MeshChangedEvent(this, getShortName(), this)); } /** Loading @@ -133,14 +123,14 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { } /** * Captures events fired by {@link cz.fidentis.analyst.mesh.core.MeshModel} and * redirects them to our listeners. * Broadcast event to registered listeners. * * @param event A fired event. * @param evt Event to be triggered. */ @Override public void meshEvent(MeshEvent event) { eventBus.post(event); public void annouceEvent(HumanFaceEvent evt) { if (evt != null) { eventBus.post(evt); } } /** Loading Loading @@ -274,8 +264,7 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public KdTree computeKdTree(boolean recompute) { if (kdTree == null || recompute) { kdTree = new KdTree(new ArrayList<>(meshModel.getFacets())); kdTree.registerListener(this); eventBus.post(new KdTreeCreated(this.getShortName())); eventBus.post(new KdTreeCreated(this, this.getShortName(), this)); } return kdTree; } Loading @@ -287,21 +276,10 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public KdTree removeKdTree() { KdTree ret = this.kdTree; this.kdTree = null; eventBus.post(new KdTreeDestroyed(this.getShortName())); eventBus.post(new KdTreeDestroyed(this, this.getShortName(), this)); return ret; } /** * Captures events fired by {@link cz.fidentis.analyst.kdtree.KdTree} and * redirects them to our listeners. * * @param event A fired event. */ @Override public void kdTreeEvent(KdTreeEvent event) { eventBus.post(event); } /** * Creates serialized dump of the human face. Event buses are not stored. * Therefore, listeners have to re-register again after recovery. Loading Comparison/src/main/java/cz/fidentis/analyst/face/events/HausdorffDistanceComputed.java 0 → 100644 +111 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.visitors.face.HausdorffDistancePrioritized; import java.util.DoubleSummaryStatistics; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * New Hausdorff distance has been computed. * * @author Radek Oslejsek */ public class HausdorffDistanceComputed extends HumanFaceEvent { private final HumanFace targetFace; private final HausdorffDistancePrioritized hdVisitor; /** * Constructor. * @param sourceFace Human face from which the HD has been computed * @param targetFace Human face towards which the HD has been computed * @param hdVisitor Visitor with HD results * @param name Event name provided by issuer * @param issuer The issuer */ public HausdorffDistanceComputed( HumanFace sourceFace, HumanFace targetFace, HausdorffDistancePrioritized hdVisitor, String name, Object issuer) { super(sourceFace, name, issuer); this.targetFace = targetFace; this.hdVisitor = hdVisitor; } /** * Returns human face from which the HD has been computed. This method * is identical to {@link #getFace()} * * @return human face from which the HD has been computed. */ public HumanFace getSourceFace() { return getFace(); } /** * Returns human face towards which the HD has been computed. * * @return human face towards which the HD has been computed. */ public HumanFace getTargetFace() { return targetFace; } /** * Returns a visitor object storing the results of HD calculations. * @return a visitor object storing the results of HD calculations. */ public HausdorffDistancePrioritized getHdVisitor() { return hdVisitor; } /** * Returns statistics of (standard) Hausdorff distance. * @return statistics of (standard) Hausdorff distance. */ public DoubleSummaryStatistics getHusdorffDistStats() { return hdVisitor.getDistances() .values() .stream() .flatMap(List::stream) .mapToDouble(Double::doubleValue) .summaryStatistics(); } /** * Returns statistics of weighted Hausdorff distance. * @return statistics of weighted Hausdorff distance. */ public DoubleSummaryStatistics getWeightedHusdorffDistStats() { final Map<MeshFacet, List<Double>> weightedDistances = new HashMap<>(hdVisitor.getDistances()); final Map<MeshFacet, List<Double>> mergedPriorities = hdVisitor.getMergedPriorities().get(getFace()); // Merge the map of distances with the map of priorities for (final Map.Entry<MeshFacet, List<Double>> facetPriorities: mergedPriorities.entrySet()) { weightedDistances.merge( facetPriorities.getKey(), facetPriorities.getValue(), (distancesList, prioritiesList) -> IntStream.range(0, distancesList.size()) .mapToDouble(i -> distancesList.get(i) * prioritiesList.get(i)) .boxed() .collect(Collectors.toList())); } return weightedDistances .values() .stream() .flatMap(List::stream) .mapToDouble(Double::doubleValue) .summaryStatistics(); } } Comparison/src/main/java/cz/fidentis/analyst/face/events/HumanFaceEvent.java 0 → 100644 +51 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.face.HumanFace; /** * The root type for events fired by the {@link cz.fidentis.analyst.face.HumanFace}. * * @author Radek Oslejsek */ public class HumanFaceEvent { private final HumanFace face; private final String name; private final Object issuer; /** * Constructor. * @param face Human face related to the event * @param name Event name provided by issuer * @param issuer The issuer */ public HumanFaceEvent(HumanFace face, String name, Object issuer) { this.face = face; this.name = name; this.issuer = issuer; } /** * Returns human face related to the event * @return human face related to the event */ public HumanFace getFace() { return face; } /** * Returns event name provided by issuer. * @return event name provided by issuer. */ public String getName() { return name; } /** * Returns the object that triggered the event. * @return the object that triggered the event. */ public Object getIssuer() { return issuer; } } Comparison/src/main/java/cz/fidentis/analyst/face/HumanFaceListener.java→Comparison/src/main/java/cz/fidentis/analyst/face/events/HumanFaceListener.java +22 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face; package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.kdtree.events.KdTreeListener; import cz.fidentis.analyst.mesh.events.MeshListener; import com.google.common.eventbus.Subscribe; /** * Objects implementing this interface can be registered with Loading @@ -10,6 +9,14 @@ import cz.fidentis.analyst.mesh.events.MeshListener; * * @author Radek Oslejsek */ public interface HumanFaceListener extends KdTreeListener, MeshListener { public interface HumanFaceListener { /** * Subscription method, which is invoked when an event appears. * * @param event A fired event. */ @Subscribe void acceptEvent(HumanFaceEvent event); } Comparison/src/main/java/cz/fidentis/analyst/face/events/KdTreeCreated.java 0 → 100644 +29 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.face.HumanFace; /** * An event fired when a new KdTree is calculated * @author Matej Kovar */ public class KdTreeCreated extends KdTreeEvent { /** * Constructor. * @param face Human face related to the event * @param name Event name provided by issuer * @param issuer The issuer */ public KdTreeCreated(HumanFace face, String name, Object issuer) { super(face, name, issuer); } @Override public boolean isCalculated() { return true; } } Loading
Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java +16 −38 Original line number Diff line number Diff line package cz.fidentis.analyst.face; import cz.fidentis.analyst.face.events.HumanFaceListener; import com.google.common.eventbus.EventBus; import cz.fidentis.analyst.face.events.HumanFaceEvent; import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.services.FeaturePointImportService; import cz.fidentis.analyst.kdtree.KdTree; import cz.fidentis.analyst.kdtree.events.KdTreeCreated; import cz.fidentis.analyst.kdtree.events.KdTreeDestroyed; import cz.fidentis.analyst.kdtree.events.KdTreeEvent; import cz.fidentis.analyst.face.events.KdTreeCreated; import cz.fidentis.analyst.face.events.KdTreeDestroyed; import cz.fidentis.analyst.face.events.MeshChangedEvent; import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.mesh.core.MeshModel; import cz.fidentis.analyst.mesh.events.MeshEvent; import cz.fidentis.analyst.mesh.events.MeshListener; import cz.fidentis.analyst.kdtree.events.KdTreeListener; import cz.fidentis.analyst.mesh.io.MeshObjLoader; import cz.fidentis.analyst.symmetry.Plane; import cz.fidentis.analyst.visitors.face.HumanFaceVisitor; Loading Loading @@ -43,18 +42,10 @@ import java.util.Objects; * Then they are informed about changes in the human automatically via methods * prescribed by the interface. * </p> * <p> * Events fired by the class: * <ul> * <li>{@link cz.fidentis.analyst.mesh.events.MeshEvent} or its sub-type if * the mesh model changes (see {@link cz.fidentis.analyst.mesh.core.MeshModel} * documentation for monitored changes).</li> * </ul> * </p> * * @author Radek Oslejsek */ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public class HumanFace implements Serializable { private MeshModel meshModel; Loading Loading @@ -87,7 +78,6 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public HumanFace(File file) throws IOException { meshModel = MeshObjLoader.read(new FileInputStream(file)); meshModel.simplifyModel(); meshModel.registerListener(this); this.id = file.getCanonicalPath(); } Loading @@ -110,7 +100,7 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { throw new IllegalArgumentException("meshModel"); } this.meshModel = meshModel; //eventBus.post(new MeshChangedEvent()); eventBus.post(new MeshChangedEvent(this, getShortName(), this)); } /** Loading @@ -133,14 +123,14 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { } /** * Captures events fired by {@link cz.fidentis.analyst.mesh.core.MeshModel} and * redirects them to our listeners. * Broadcast event to registered listeners. * * @param event A fired event. * @param evt Event to be triggered. */ @Override public void meshEvent(MeshEvent event) { eventBus.post(event); public void annouceEvent(HumanFaceEvent evt) { if (evt != null) { eventBus.post(evt); } } /** Loading Loading @@ -274,8 +264,7 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public KdTree computeKdTree(boolean recompute) { if (kdTree == null || recompute) { kdTree = new KdTree(new ArrayList<>(meshModel.getFacets())); kdTree.registerListener(this); eventBus.post(new KdTreeCreated(this.getShortName())); eventBus.post(new KdTreeCreated(this, this.getShortName(), this)); } return kdTree; } Loading @@ -287,21 +276,10 @@ public class HumanFace implements MeshListener, KdTreeListener, Serializable { public KdTree removeKdTree() { KdTree ret = this.kdTree; this.kdTree = null; eventBus.post(new KdTreeDestroyed(this.getShortName())); eventBus.post(new KdTreeDestroyed(this, this.getShortName(), this)); return ret; } /** * Captures events fired by {@link cz.fidentis.analyst.kdtree.KdTree} and * redirects them to our listeners. * * @param event A fired event. */ @Override public void kdTreeEvent(KdTreeEvent event) { eventBus.post(event); } /** * Creates serialized dump of the human face. Event buses are not stored. * Therefore, listeners have to re-register again after recovery. Loading
Comparison/src/main/java/cz/fidentis/analyst/face/events/HausdorffDistanceComputed.java 0 → 100644 +111 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.face.HumanFace; import cz.fidentis.analyst.mesh.core.MeshFacet; import cz.fidentis.analyst.visitors.face.HausdorffDistancePrioritized; import java.util.DoubleSummaryStatistics; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * New Hausdorff distance has been computed. * * @author Radek Oslejsek */ public class HausdorffDistanceComputed extends HumanFaceEvent { private final HumanFace targetFace; private final HausdorffDistancePrioritized hdVisitor; /** * Constructor. * @param sourceFace Human face from which the HD has been computed * @param targetFace Human face towards which the HD has been computed * @param hdVisitor Visitor with HD results * @param name Event name provided by issuer * @param issuer The issuer */ public HausdorffDistanceComputed( HumanFace sourceFace, HumanFace targetFace, HausdorffDistancePrioritized hdVisitor, String name, Object issuer) { super(sourceFace, name, issuer); this.targetFace = targetFace; this.hdVisitor = hdVisitor; } /** * Returns human face from which the HD has been computed. This method * is identical to {@link #getFace()} * * @return human face from which the HD has been computed. */ public HumanFace getSourceFace() { return getFace(); } /** * Returns human face towards which the HD has been computed. * * @return human face towards which the HD has been computed. */ public HumanFace getTargetFace() { return targetFace; } /** * Returns a visitor object storing the results of HD calculations. * @return a visitor object storing the results of HD calculations. */ public HausdorffDistancePrioritized getHdVisitor() { return hdVisitor; } /** * Returns statistics of (standard) Hausdorff distance. * @return statistics of (standard) Hausdorff distance. */ public DoubleSummaryStatistics getHusdorffDistStats() { return hdVisitor.getDistances() .values() .stream() .flatMap(List::stream) .mapToDouble(Double::doubleValue) .summaryStatistics(); } /** * Returns statistics of weighted Hausdorff distance. * @return statistics of weighted Hausdorff distance. */ public DoubleSummaryStatistics getWeightedHusdorffDistStats() { final Map<MeshFacet, List<Double>> weightedDistances = new HashMap<>(hdVisitor.getDistances()); final Map<MeshFacet, List<Double>> mergedPriorities = hdVisitor.getMergedPriorities().get(getFace()); // Merge the map of distances with the map of priorities for (final Map.Entry<MeshFacet, List<Double>> facetPriorities: mergedPriorities.entrySet()) { weightedDistances.merge( facetPriorities.getKey(), facetPriorities.getValue(), (distancesList, prioritiesList) -> IntStream.range(0, distancesList.size()) .mapToDouble(i -> distancesList.get(i) * prioritiesList.get(i)) .boxed() .collect(Collectors.toList())); } return weightedDistances .values() .stream() .flatMap(List::stream) .mapToDouble(Double::doubleValue) .summaryStatistics(); } }
Comparison/src/main/java/cz/fidentis/analyst/face/events/HumanFaceEvent.java 0 → 100644 +51 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.face.HumanFace; /** * The root type for events fired by the {@link cz.fidentis.analyst.face.HumanFace}. * * @author Radek Oslejsek */ public class HumanFaceEvent { private final HumanFace face; private final String name; private final Object issuer; /** * Constructor. * @param face Human face related to the event * @param name Event name provided by issuer * @param issuer The issuer */ public HumanFaceEvent(HumanFace face, String name, Object issuer) { this.face = face; this.name = name; this.issuer = issuer; } /** * Returns human face related to the event * @return human face related to the event */ public HumanFace getFace() { return face; } /** * Returns event name provided by issuer. * @return event name provided by issuer. */ public String getName() { return name; } /** * Returns the object that triggered the event. * @return the object that triggered the event. */ public Object getIssuer() { return issuer; } }
Comparison/src/main/java/cz/fidentis/analyst/face/HumanFaceListener.java→Comparison/src/main/java/cz/fidentis/analyst/face/events/HumanFaceListener.java +22 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face; package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.kdtree.events.KdTreeListener; import cz.fidentis.analyst.mesh.events.MeshListener; import com.google.common.eventbus.Subscribe; /** * Objects implementing this interface can be registered with Loading @@ -10,6 +9,14 @@ import cz.fidentis.analyst.mesh.events.MeshListener; * * @author Radek Oslejsek */ public interface HumanFaceListener extends KdTreeListener, MeshListener { public interface HumanFaceListener { /** * Subscription method, which is invoked when an event appears. * * @param event A fired event. */ @Subscribe void acceptEvent(HumanFaceEvent event); }
Comparison/src/main/java/cz/fidentis/analyst/face/events/KdTreeCreated.java 0 → 100644 +29 −0 Original line number Diff line number Diff line package cz.fidentis.analyst.face.events; import cz.fidentis.analyst.face.HumanFace; /** * An event fired when a new KdTree is calculated * @author Matej Kovar */ public class KdTreeCreated extends KdTreeEvent { /** * Constructor. * @param face Human face related to the event * @param name Event name provided by issuer * @param issuer The issuer */ public KdTreeCreated(HumanFace face, String name, Object issuer) { super(face, name, issuer); } @Override public boolean isCalculated() { return true; } }