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

Merge branch 'feat-fine-tuning-landmarks' into 'master'

Feat fine tuning landmarks

See merge request grp-fidentis/analyst2!422
parents 27969bce c56b0a52
Loading
Loading
Loading
Loading
+30 −13
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ public class FpListInfoPanel extends FpListAbstractPanel<FpListInfoPanel.Row> {
    public static final String ACTION_CHANGE_TYPE_COLOR = "changes color of a selected type of feature point";
    public static final String ACTION_EDIT_LANDMARK = "edit landmark";

    public static final String TOOL_TIP_TEXT_ON_THE_FACE = "Is on the face";
    public static final String TOOL_TIP_TEXT_CLOSER_THAN_THRESHOLD = "Is closer than distance threshold";
    public static final String TOOL_TIP_TEXT_FURTHER_THAN_THRESHOLD = "Is further than distance threshold";
    public static final String TOOL_TIP_TEXT_OFF_THE_MESH = "Is too far from face";
@@ -143,23 +142,41 @@ public class FpListInfoPanel extends FpListAbstractPanel<FpListInfoPanel.Row> {
     * @return color indicator
     */
    private JLabel createColorIndicator(Landmark featurePoint, DrawableFeaturePoints drFeaturePoints) {
        Color color;
        Color color = Color.GRAY;
        MeshVicinity.Location fpType = featurePoint.getMeshVicinity().getPositionType(drFeaturePoints.getDistanceThreshold());
        String toolTipText;
        String toolTipText = "";

        if (featurePoint.isUserDefinedLandmark()) {
            color = drFeaturePoints.getCustomFpColor();
            toolTipText = TOOL_TIP_TEXT_ON_THE_FACE;
        } else if (fpType == MeshVicinity.Location.ON_THE_MESH) {
            switch (fpType) {
                case ON_THE_MESH -> {
                    color = drFeaturePoints.getCustomOnTheMeshColor();
                    toolTipText = TOOL_TIP_TEXT_CLOSER_THAN_THRESHOLD;
                }
                case CLOSE_TO_MESH -> {
                    color = drFeaturePoints.getCustomCloseToMeshColor();
                    toolTipText = TOOL_TIP_TEXT_FURTHER_THAN_THRESHOLD;
                }
                case OFF_THE_MESH -> {
                    color = drFeaturePoints.getCustomOffTheMeshColor();
                    toolTipText = TOOL_TIP_TEXT_OFF_THE_MESH;
                }
            }
        } else {
            switch (fpType) {
                case ON_THE_MESH -> {
                    color = drFeaturePoints.getOnTheMeshColor();
                    toolTipText = TOOL_TIP_TEXT_CLOSER_THAN_THRESHOLD;
        } else if (fpType == MeshVicinity.Location.CLOSE_TO_MESH) {
                }
                case CLOSE_TO_MESH -> {
                    color = drFeaturePoints.getCloseToMeshColor();
                    toolTipText = TOOL_TIP_TEXT_FURTHER_THAN_THRESHOLD;
        } else {
                }
                case OFF_THE_MESH -> {
                    color = drFeaturePoints.getOffTheMeshColor();
                    toolTipText = TOOL_TIP_TEXT_OFF_THE_MESH;
                }
            }
        }

        JLabel colorIndicator = new JLabel();
        colorIndicator.setToolTipText(toolTipText);
+152 −18
Original line number Diff line number Diff line
package cz.fidentis.analyst.gui.task.featurepoints;

import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.canvas.MouseClickListener;
import cz.fidentis.analyst.data.face.*;
import cz.fidentis.analyst.data.face.events.HumanFaceSelectedEvent;
import cz.fidentis.analyst.data.face.events.LandmarksChangedEvent;
@@ -23,6 +24,8 @@ import cz.fidentis.analyst.gui.task.featurepoints.windows.AddEditLmWindow;
import cz.fidentis.analyst.project.Task;

import javax.swing.*;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.*;
@@ -123,6 +126,7 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
                addFeaturePoint();
                skeleton.loadSkeleton(getPrimaryFeaturePoints().getFeaturePoints());
                getControlPanel().changeStateButtonsWhenEdit(false);
                setColorsOfFeaturePoints();
                break;
                
            case AbstractAddEditWindow.ACTION_CANCEL_ADD_LANDMARK:
@@ -139,20 +143,25 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>

            case AbstractAddEditWindow.ACTION_SAVE_CHANGES:
                if (saveChanges()) {
                    getControlPanel().setVisibleMovePanel(false);
                    getControlPanel().changeStateButtonsWhenEdit(false);
                    hoverFeaturePoint(workingFP, false);
                    workingFP = null;
                    workingFpMode = DISABLE;
                    skeleton.loadSkeleton(getPrimaryFeaturePoints().getFeaturePoints());
                    setColorsOfFeaturePoints();
                }
                break;

            case AbstractAddEditWindow.ACTION_CANCEL_CHANGES:
                closeEditLandmarkWindow();
                getControlPanel().setVisibleMovePanel(false);
                workingFP.rollbackPosition();
                hoverFeaturePoint(workingFP, false);
                workingFP = null;
                workingFpMode = DISABLE;
                getControlPanel().changeStateButtonsWhenEdit(false);
                setColorsOfFeaturePoints();
                break;
                
            case FeaturePointsPanel.ACTION_COMMAND_REMOVE_FEATURE_POINT:
@@ -179,11 +188,16 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
                break;

            case FpListInfoPanel.ACTION_COMMAND_FEATURE_POINT_HOVER_IN:
                if (!workingFpMode.equals(ENABLE_CHANGE_FP_POSITION)) {
                    hoverFeaturePoint((LoadedActionEvent) ae, true);
                }
                break;
                
            case FpListInfoPanel.ACTION_COMMAND_FEATURE_POINT_HOVER_OUT:
                if (!workingFpMode.equals(ENABLE_CHANGE_FP_POSITION)) {
                    hoverFeaturePoint((LoadedActionEvent) ae, false);
                    setColorsOfFeaturePoints();
                }
                break;
                
            case FeaturePointsPanel.ACTION_CHANGE_DISTANCE_THRESHOLD:
@@ -191,6 +205,12 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
                setColorsOfFeaturePoints();
                break;

            case FeaturePointsPanel.ACTION_CHANGE_FP_SIZE:
                double newSize = getControlPanel().getSizeFpSlider().getValue().doubleValue();
                getPrimaryFeaturePoints().setLandmarkRadius(newSize);
                renderScene();
                break;

            case SelectFpButtonsPanel.ACTION_SELECT_BY_MESH_VICINITY:
                setSelectedByMeshVicinity((LoadedActionEvent) ae);
                setColorsOfFeaturePoints();
@@ -218,6 +238,10 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
                        .refreshPanel(this, getPrimaryFeaturePoints(), selectedFeaturePoints);
                break;

            case FeaturePointsPanel.ACTION_MOVE_FEATURE_POINT:
                moveFeaturePointOnMesh(ae);
                break;
                
            case FeaturePointsPanel.ACTION_SHOW_HIDE_SKELETON:
                skeletonVisible = ((JCheckBox) ae.getSource()).isSelected();
                skeleton.show(skeletonVisible);
@@ -251,9 +275,9 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>

    @Override
    public void acceptEvent(HumanFaceEvent event) {
        if (event instanceof HumanFaceSelectedEvent && !workingFpMode.equals(DISABLE)) {
        if (event instanceof HumanFaceSelectedEvent){
            RayIntersection closestIntersection = ((HumanFaceSelectedEvent) event).getIntersection();

            if (!workingFpMode.equals(DISABLE)) {
                if (closestIntersection != null && workingFpMode.equals(ENABLE_ADD_FP)) {
                    getPrimaryFeaturePoints().removeFeaturePoint(workingFP);
                    workingFP = LandmarksFactory.creteWorkingLandmark(closestIntersection.getPosition());
@@ -268,10 +292,53 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
                    workingFP.setPosition(closestIntersection.getPosition());
                    workingFP.setMeshVicinity(new MeshVicinity(0, closestIntersection.getPosition()));
                }
            }

            if (event.getName().equals(MouseClickListener.CONTROL_CLICK_EVENT_NAME)) {
                if (closestIntersection != null) {
                    Landmark closestLandmark = findNearLandmark(closestIntersection.getPosition());
                    if (closestLandmark != null) {
                        selectFeaturePoint(closestLandmark);
                        setColorsOfFeaturePoints();
                        getControlPanel().getStandardFeaturePointListPanel()
                                .refreshPanel(this, getPrimaryFeaturePoints(), selectedFeaturePoints);
                        getControlPanel().getUserFeaturePointListPanel()
                                .refreshPanel(this, getPrimaryFeaturePoints(), selectedFeaturePoints);
                    }
                }
            }

            if (event.getName().equals(MouseClickListener.DOUBLE_CLICK_EVENT_NAME)) {
                if (closestIntersection != null) {
                    Landmark closestLandmark = findNearLandmark(closestIntersection.getPosition());
                    if (closestLandmark != null) {
                        startEditLandmark(closestLandmark);
                    }
                }
            }
            renderScene();
        }
    }

    /**
     * Finds the closest landmark to the given position of the intersection of click and the face
     * @param position position of the intersection, where to search for the closest landmark
     * @return the closest landmark to the given position
     */
    private Landmark findNearLandmark(Point3d position) {
        double maxDistance = DrawableFeaturePoints.FP_DEFAULT_RADIUS_SIZE * 2;
        Landmark closestLandmark = null;

        for (Landmark landmark : getPrimaryFeaturePoints().getFeaturePoints()) {
            double distance = position.distance(landmark.getPosition());
            if (distance < maxDistance) {
                maxDistance = distance;
                closestLandmark = landmark;
            }
        }
        return closestLandmark;
    }

    /**
     * Changes the color of the face's feature point when the cursor hovers over the feature point's name.
     * The landmark is received as the data payload of {@code actionEvent}.
@@ -308,6 +375,15 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
     */
    private void selectFeaturePoint(LoadedActionEvent actionEvent) {
        final Landmark landmark = (Landmark) actionEvent.getData();
        selectFeaturePoint(landmark);
    }

    /**
     * Selects or deselects a feature point
     *
     * @param landmark Landmark to be selected or deselected
     */
    private void selectFeaturePoint(Landmark landmark) {
        if (landmark == null) {
            return;
        }
@@ -392,6 +468,10 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
     * Updates the correct colors of all feature points in rendered scene
     */
    private void setColorsOfFeaturePoints() {
        if (workingFpMode.equals(ENABLE_CHANGE_FP_POSITION)) {
            return;
        }

        for (Landmark fp : getPrimaryFeaturePoints().getFeaturePoints()) {
            Color color;
            if (selectedFeaturePoints.contains(fp)) {
@@ -484,6 +564,41 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
        }
    }

    /**
     * Moves the feature point based on source JButton, then pins it to the mesh.
     * The feature point is moved by the distance set in the movement spinner.
     *
     * @param ae ActionEvent
     */
    private void moveFeaturePointOnMesh(ActionEvent ae) {
        if (workingFP == null) {
            return;
        }

        Vector3d moveVector = new Vector3d();
        if (ae.getSource() == getControlPanel().getMoveRightButton()) {
            moveVector.set(getControlPanel().getMovementSlider().getValue().doubleValue(), 0, 0);
        } else if (ae.getSource() == getControlPanel().getMoveLeftButton()) {
            moveVector.set(-getControlPanel().getMovementSlider().getValue().doubleValue(), 0, 0);
        } else if (ae.getSource() == getControlPanel().getMoveUpButton()) {
            moveVector.set(0, getControlPanel().getMovementSlider().getValue().doubleValue(), 0);
        } else if (ae.getSource() == getControlPanel().getMoveDownButton()) {
            moveVector.set(0, -getControlPanel().getMovementSlider().getValue().doubleValue(), 0);
        } else if (ae.getSource() == getControlPanel().getRollbackMoveButton()) {
            workingFP.rollbackPosition();
            return;
        }

        Point3d newPosition = new Point3d(workingFP.getPosition());
        newPosition.add(moveVector);

        RayIntersection intersection = getCanvas().castRay(newPosition, new Vector3d(0, 0, 1)).second();

        workingFP.setPosition(intersection.getPosition());
        workingFP.setMeshVicinity(new MeshVicinity(0, intersection.getPosition()));
        renderScene();
    }

    /**
     * Starts the edit window for a landmark.
     * Popups the edit window, allow to change position and properties of the landmark.
@@ -491,11 +606,22 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
     * @param ae LoadedActionEvent
     */
    private void startEditLandmark(LoadedActionEvent ae) {
        getControlPanel().changeStateButtonsWhenEdit(true);
        Landmark editLand = (Landmark) ae.getData();
        startEditLandmark((Landmark) ae.getData());
    }

    /**
     * Starts the edit window for a landmark.
     * Popups the edit window, allow to change position and properties of the landmark.
     * Sets current landmark as the working landmark.
     *
     * @param editLand Landmark to be edited
     */
    private void startEditLandmark(Landmark editLand) {
        if (editLand == null) {
            return;
        }
        getControlPanel().changeStateButtonsWhenEdit(true);
        getControlPanel().setVisibleMovePanel(true);
        hoverFeaturePoint(editLand, true);

        workingFpMode = ENABLE_CHANGE_FP_POSITION;
@@ -544,6 +670,7 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
            workingFP.setDescription(addEditWindow.getLandmarkDescription());
            getControlPanel().getUserFeaturePointListPanel().refreshPanel(this, getPrimaryFeaturePoints(), selectedFeaturePoints);
        }
        workingFP.savePosition();

        closeEditLandmarkWindow();
        return true;
@@ -620,7 +747,9 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
        currentColors.add(getPrimaryFeaturePoints().getOnTheMeshColor());
        currentColors.add(getPrimaryFeaturePoints().getCloseToMeshColor());
        currentColors.add(getPrimaryFeaturePoints().getOffTheMeshColor());
        currentColors.add(getPrimaryFeaturePoints().getCustomFpColor());
        currentColors.add(getPrimaryFeaturePoints().getCustomOnTheMeshColor());
        currentColors.add(getPrimaryFeaturePoints().getCustomCloseToMeshColor());
        currentColors.add(getPrimaryFeaturePoints().getCustomOffTheMeshColor());
        currentColors.add(FEATURE_POINT_HIGHLIGHT_COLOR);
        currentColors.add(FEATURE_POINT_HOVER_COLOR);

@@ -632,9 +761,14 @@ public class FeaturePointsAction extends ControlPanelAction<FeaturePointsPanel>
            getPrimaryFeaturePoints().setCloseToMeshColor(newColor);
        } else if (oldColor == getPrimaryFeaturePoints().getOffTheMeshColor()) {
            getPrimaryFeaturePoints().setOffTheMeshColor(newColor);
        } else if (oldColor == getPrimaryFeaturePoints().getCustomOnTheMeshColor()) {
            getPrimaryFeaturePoints().setCustomOnTheMeshColor(newColor);
        } else if (oldColor == getPrimaryFeaturePoints().getCustomCloseToMeshColor()) {
            getPrimaryFeaturePoints().setCustomCloseToMeshColor(newColor);
        } else {
            getPrimaryFeaturePoints().setCustomFpColor(newColor);
            getPrimaryFeaturePoints().setCustomOffTheMeshColor(newColor);
        }

        ((JLabel) ae.getSource()).setBackground(newColor);
        setColorsOfFeaturePoints();
        getControlPanel()
+216 −19

File changed.

Preview size limit exceeded, changes collapsed.

+198 −20

File changed.

Preview size limit exceeded, changes collapsed.

+13 −0
Original line number Diff line number Diff line
@@ -34,3 +34,16 @@ FeaturePointsPanel.pinPrimarySelectedFpButton.text_2=\u26b2
FeaturePointsPanel.pinSecondarySelectedFpButton.toolTipText=Pin selected to mesh
FeaturePointsPanel.pinSecondarySelectedFpButton.text=\u26b2
SelectFpButtonsPanel.border.title=Selection
FeaturePointsPanel.movementSlider.toolTipText=Points to move
FeaturePointsPanel.rollbackMoveButton.toolTipText=Rollback current move
FeaturePointsPanel.rollbackMoveButton.text=\u21ba
FeaturePointsPanel.moveDownButton.toolTipText=Move down
FeaturePointsPanel.moveDownButton.text=\u25bc
FeaturePointsPanel.moveUpButton.toolTipText=Move up
FeaturePointsPanel.moveUpButton.text=\u25b2
FeaturePointsPanel.moveLeftButton.toolTipText=Move left
FeaturePointsPanel.moveLeftButton.text=\u25c0
FeaturePointsPanel.moveRightButton.toolTipText=Move right
FeaturePointsPanel.moveRightButton.text=\u25b6
FeaturePointsPanel.moveFpPanel.border.title=Fine tune feature point:
FeaturePointsPanel.sizePanel.border.title=Size of feature points:
Loading