Commit f3f3b606 authored by Radek Ošlejšek's avatar Radek Ošlejšek
Browse files

Resolve "Introduce view toolbox"

parent 80f08293
Loading
Loading
Loading
Loading
+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;
@@ -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;
    
@@ -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();
    }
    
@@ -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));
    }

    /**
@@ -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);
        }
    }

    /**
@@ -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;
    }
@@ -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.
+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();
    }
    
}
+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;
    }
}
+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 
@@ -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);
    
}
+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