Skip to content
Snippets Groups Projects
FaceStatePanel.java 31.3 KiB
Newer Older
package cz.fidentis.analyst.faceState;
import cz.fidentis.analyst.project.Project;
import cz.fidentis.analyst.core.ControlPanel;
import cz.fidentis.analyst.face.HumanFace;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
Matej Kovár's avatar
Matej Kovár committed
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.imageio.ImageIO;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import org.imgscalr.Scalr;

/**
 *
 * @author Matej Kovar
 */
public class FaceStatePanel extends ControlPanel {
    private final ImageIcon anonymousFace = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "face160x160.png"));
    public static final String DEFAULT_ICON = "head28x28.png";
    public static final String PRIMARY_FACE_ICON = "primaryFace28x28.png";
    public static final String SECONDARY_FACE_ICON = "secondaryFace28x28.png";
    public static final String NAME = "Face State";
    
    /**
     * All types of icons which this panel can have
     * @author Matej Kovar
     */
    public enum TypeOfIcon {
        DEFAULT,
        MANY_TO_MANY_PRIMARY,
        MANY_TO_MANY_SECONDARY
    }
    
    private TypeOfIcon typeOfIcon = TypeOfIcon.DEFAULT;
    
    // Loaded geometry info of face
    private Map<String, FaceGeometryInfo> loadedFaces = new HashMap<>();

    /**
     * Panel with face information
     * @param loadFaceListener ActionListener listens when load face button is clicked
     */
    public FaceStatePanel(ActionListener loadFaceListener) {
        
        this.setName(NAME);
        initComponents();
        loadInfoButton.addActionListener(loadFaceListener);
        loadInfoButton.setToolTipText("Loads face geometry info from file in specified file path");
        //210 140
    }
    
    /**
     * Panel with face information
     * @param project where path to face is stored
     * @param faceName name of the displayed face
     * @param path path to face
     */
    public FaceStatePanel(Project project, String faceName, Path path) {
    
        // Listener for loading currently selected face (to show face state)
        ActionListener listenerLoadFace = (ActionEvent e) -> {
            HumanFace face = project.loadFace(faceName);
            this.loadFaceGeometryInfo(face);
            this.showFaceState(faceName, path);
        };
        
        this.setName(NAME);
        initComponents();
        loadInfoButton.addActionListener(listenerLoadFace);
        loadInfoButton.setToolTipText("Loads face geometry info from file in specified file path");
        //this.project = project;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        filePanel = new javax.swing.JPanel();
        pathLabel = new javax.swing.JLabel();
        pathOutput = new javax.swing.JLabel();
Matej Kovár's avatar
Matej Kovár committed
        sizeLabel = new javax.swing.JLabel();
        sizeOutput = new javax.swing.JLabel();
Matej Kovár's avatar
Matej Kovár committed
        featurePointsLabel = new javax.swing.JLabel();
        featurePointsOutput = new javax.swing.JLabel();
        previewLabel = new javax.swing.JLabel();
        previewOutput = new javax.swing.JLabel();
        textureLabel = new javax.swing.JLabel();
        textureOutput = new javax.swing.JLabel();
        geometryPanel = new javax.swing.JPanel();
        verticesLabel = new javax.swing.JLabel();
        verticesOutput = new javax.swing.JLabel();
        facetsLabel = new javax.swing.JLabel();
        facetsOutput = new javax.swing.JLabel();
        fpLabel = new javax.swing.JLabel();
        jComboBox1 = new javax.swing.JComboBox<>();
        loadInfoButton = new javax.swing.JButton();
        photoPanel = new javax.swing.JPanel();
        photo = new javax.swing.JLabel();

        filePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.filePanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 14))); // NOI18N
        pathLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.pathLabel.text")); // NOI18N
        pathLabel.setEnabled(false);

Matej Kovár's avatar
Matej Kovár committed
        org.openide.awt.Mnemonics.setLocalizedText(pathOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.pathOutput.text")); // NOI18N

        sizeLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(sizeLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.sizeLabel.text")); // NOI18N
        sizeLabel.setEnabled(false);

        org.openide.awt.Mnemonics.setLocalizedText(sizeOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.sizeOutput.text")); // NOI18N

        featurePointsLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
Matej Kovár's avatar
Matej Kovár committed
        org.openide.awt.Mnemonics.setLocalizedText(featurePointsLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.featurePointsLabel.text")); // NOI18N
        featurePointsLabel.setEnabled(false);

        org.openide.awt.Mnemonics.setLocalizedText(featurePointsOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.featurePointsOutput.text")); // NOI18N

        previewLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
Matej Kovár's avatar
Matej Kovár committed
        org.openide.awt.Mnemonics.setLocalizedText(previewLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.previewLabel.text")); // NOI18N
        previewLabel.setEnabled(false);

        org.openide.awt.Mnemonics.setLocalizedText(previewOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.previewOutput.text")); // NOI18N

        textureLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
Matej Kovár's avatar
Matej Kovár committed
        org.openide.awt.Mnemonics.setLocalizedText(textureLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.textureLabel.text")); // NOI18N
        textureLabel.setEnabled(false);

        org.openide.awt.Mnemonics.setLocalizedText(textureOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.textureOutput.text")); // NOI18N

        javax.swing.GroupLayout filePanelLayout = new javax.swing.GroupLayout(filePanel);
        filePanel.setLayout(filePanelLayout);
        filePanelLayout.setHorizontalGroup(
            filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
Matej Kovár's avatar
Matej Kovár committed
                    .addComponent(featurePointsLabel)
                    .addComponent(textureLabel)
                    .addComponent(previewLabel)
                    .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(sizeLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(pathLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addGap(10, 10, 10)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(sizeOutput, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 428, Short.MAX_VALUE)
                    .addComponent(featurePointsOutput, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pathOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(previewOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(textureOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(0, 0, Short.MAX_VALUE))
        );
        filePanelLayout.setVerticalGroup(
            filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(pathLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pathOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(sizeLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(sizeOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(featurePointsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(featurePointsOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(previewLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(previewOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(textureLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(textureOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(14, 14, 14))
        geometryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.geometryPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 14))); // NOI18N
        verticesLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(verticesLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.verticesLabel.text")); // NOI18N
        verticesLabel.setEnabled(false);
        org.openide.awt.Mnemonics.setLocalizedText(verticesOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.verticesOutput.text")); // NOI18N
        facetsLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(facetsLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.facetsLabel.text")); // NOI18N
        facetsLabel.setEnabled(false);
        org.openide.awt.Mnemonics.setLocalizedText(facetsOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.facetsOutput.text")); // NOI18N
        fpLabel.setFont(new java.awt.Font("Tahoma", 1, 10)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(fpLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.fpLabel.text")); // NOI18N
        fpLabel.setEnabled(false);
        loadInfoButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(loadInfoButton, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.loadInfoButton.text")); // NOI18N
        javax.swing.GroupLayout geometryPanelLayout = new javax.swing.GroupLayout(geometryPanel);
        geometryPanel.setLayout(geometryPanelLayout);
        geometryPanelLayout.setHorizontalGroup(
            geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(geometryPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(geometryPanelLayout.createSequentialGroup()
                        .addComponent(verticesLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(verticesOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, geometryPanelLayout.createSequentialGroup()
                        .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(facetsLabel)
                            .addComponent(fpLabel))
                        .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(geometryPanelLayout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 286, Short.MAX_VALUE)
                                .addComponent(loadInfoButton)
                                .addGap(51, 51, 51))
                            .addGroup(geometryPanelLayout.createSequentialGroup()
                                .addGap(20, 20, 20)
                                .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jComboBox1, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(facetsOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))))
                .addContainerGap())
        geometryPanelLayout.setVerticalGroup(
            geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(geometryPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(verticesLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(verticesOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(facetsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(facetsOutput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(geometryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(fpLabel)
                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(53, 53, 53)
                .addComponent(loadInfoButton)
                .addContainerGap(34, Short.MAX_VALUE))
        photoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.photoPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 14))); // NOI18N

        photo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face160x160.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(photo, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.photo.text")); // NOI18N
        photo.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                photoMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout photoPanelLayout = new javax.swing.GroupLayout(photoPanel);
        photoPanel.setLayout(photoPanelLayout);
        photoPanelLayout.setHorizontalGroup(
            photoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(photoPanelLayout.createSequentialGroup()
                .addGap(55, 55, 55)
                .addComponent(photo)
                .addGap(55, 55, 55))
        );
        photoPanelLayout.setVerticalGroup(
            photoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(photoPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(photo)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(filePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(geometryPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(photoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addComponent(photoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(filePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(geometryPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        filePanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.filePanel.AccessibleContext.accessibleName")); // NOI18N
    }// </editor-fold>//GEN-END:initComponents
    public void setTypeOfIcon(TypeOfIcon typeOfIcon) {
        this.typeOfIcon = typeOfIcon;
    }
    
    
    private void photoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_photoMouseClicked
        
        if (previewFace != null) {
            JOptionPane.showMessageDialog(this.getParent(), previewFace, "Preview Image", JOptionPane.PLAIN_MESSAGE);
        }
       
    }//GEN-LAST:event_photoMouseClicked
    
    /**
     * Shows face information on panel
     * @param faceName String
     * @param path Path
     */
    public void showFaceState(String faceName, Path path) {
        photo.setIcon(getPhoto(path));
        pathOutput.setText(getPathText(path));
        sizeOutput.setText(getSizeText(path));
Matej Kovár's avatar
Matej Kovár committed
        featurePointsOutput.setText(getFeaturePointsText(path));
        previewOutput.setText(getPreviewText(path));
        textureOutput.setText(getTextureText(path));
        verticesOutput.setText(getNumberOfVertices(faceName));
        facetsOutput.setText(getNumberOfFacets(faceName));
        loadFeaturePoints(faceName);
    }
    
    @Override
    public ImageIcon getIcon() {
        switch (typeOfIcon) {
            case MANY_TO_MANY_PRIMARY:
                return new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + PRIMARY_FACE_ICON));
            case MANY_TO_MANY_SECONDARY:
                return new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + SECONDARY_FACE_ICON));
            default:
                break;
        }
        return new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + DEFAULT_ICON));
    }
    
    /**
     * Gets photo which would be displayed on photo panel
     * @param path Path
     * @return ImageIcon either loaded face preview or anonymous face when preview is not found
     */
    private ImageIcon getPhoto(Path path) {
        previewFace = null;
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  
        if (path != null && path.toFile().exists()) {
            String pathString = path.toString();
            Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview.jpg"));
                BufferedImage image = ImageIO.read(preview.toFile());
                BufferedImage zoomedImage = Scalr.resize(image, (int)screenSize.getWidth() / 2, (int)screenSize.getHeight() / 2);
                BufferedImage smallImage = Scalr.resize(image, 240, 160);
                
                previewFace = new ImageIcon(zoomedImage);
                photo.setToolTipText("Click to enlarge the image");
                return new ImageIcon(smallImage);
                
            } catch (IOException ex) {
                //Exceptions.printStackTrace(ex);)
            }
Matej Kovár's avatar
Matej Kovár committed
        }
        photo.setToolTipText("");
        return anonymousFace;
    /**
     * Gets path text
     * @param path Path
     * @return String path or blank string
     */
    private String getPathText(Path path) {
        
        if (path != null) {
            pathLabel.setEnabled(true);
            return path.toString();
        }
        pathLabel.setEnabled(false);
        return "";
    }
    
    /**
     * Gets size of model ".obj"
     * @param path Path
     * @return String size in kB or blank string
     */
    private String getSizeText(Path path) {
        
        if (path != null && path.toFile().exists()) {

            try {
                long bytes = Files.size(path);
                sizeLabel.setEnabled(true);
                return String.format("%,d kB", bytes / 1024);
                
            } catch (IOException ex) {
                //Exceptions.printStackTrace(ex);
                // TODO HANDLE EXCEPTION
            }
        }
        sizeLabel.setEnabled(false);
        return "";
    }
    
    /**
     * Gets path to feature points file
     * @param path Path to face
     * @return String path to feature points file or blank string
     */
Matej Kovár's avatar
Matej Kovár committed
    private String getFeaturePointsText(Path path) {
        
        if (path != null) {
            featurePointsLabel.setEnabled(true);
            
            String filePath = path.toString().split(".obj")[0] + "_landmarks.csv";
            if ((new File(filePath)).exists()) {
                return filePath;
            }

            filePath = path.toString().split("_ECA")[0] + "_landmarks.csv";
            if ((new File(filePath)).exists()) {
                return filePath;
            }

            filePath = path.toString().split("_CA")[0] + "_landmarks.csv";
            if ((new File(filePath)).exists()) {
                return filePath;
            }
        }
        
        featurePointsLabel.setEnabled(false);
        return "";   
    }
    
    /**
     * Gets path to preview file
     * @param path Path to face
     * @return String path to preview file or blank string
     */
Matej Kovár's avatar
Matej Kovár committed
    private String getPreviewText(Path path) {
        
        if (path != null) {
            previewLabel.setEnabled(true);
            
            String filePath = path.toString().split(".obj")[0] + "_preview.jpg";
            
            if ((new File(filePath)).exists()) {
                return filePath;
            }
        }
        
        previewLabel.setEnabled(false);
        return "";
    }
    
    /**
     * Gets path to texture file
     * @param path Path to face
     * @return String path to texture file or blank string
     */
Matej Kovár's avatar
Matej Kovár committed
    private String getTextureText(Path path) {
        
        if (path != null) {
            textureLabel.setEnabled(true);
            
            String filePath = path.toString().split(".obj")[0] + ".jpg";
            
            if ((new File(filePath)).exists()) {
                return filePath;
            }
        }
        
        textureLabel.setEnabled(false);
        return "";
        
    }
    
     * Gets number of vertices from face mesh model
     * @param faceName String name of face
     * @return String number of vertices or blank string
    private String getNumberOfVertices(String faceName) {
        if (faceName != null && loadedFaces.get(faceName) != null) {
            verticesLabel.setEnabled(true);
            return "" + loadedFaces.get(faceName).getVerticesInfo();
        verticesLabel.setEnabled(false);
        return "";
    }
    
    /**
     * Gets number of facets from face mesh model
     * @param faceName String name of face
     * @return String number of facets or blank string
     */
    private String getNumberOfFacets(String faceName) {
        if (faceName != null && loadedFaces.get(faceName) != null) {
            facetsLabel.setEnabled(true);
            return "" + loadedFaces.get(faceName).getFecetsInfo();
        
        facetsLabel.setEnabled(false);
        return "";
     * Loads geometry info of face to loadedFaces
     * @param faceName String name of face
     */
    public void loadFaceGeometryInfo(String faceName) {
        
        FaceGeometryInfo faceGeometryInfo = new FaceGeometryInfo(getNumberOfVertices(faceName), getNumberOfFacets(faceName), getFeaturePoints(faceName));
        loadedFaces.put(faceName, faceGeometryInfo);
        
    }
    
    /**
     * Gets feature points of face
     * @param faceName String name of face
     * @return feature points or empty list
    private List<String> getFeaturePoints(String faceName) {
        List<String> featurePoints = Collections.EMPTY_LIST;
        if (loadedFaces.get(faceName) != null) {
            featurePoints = loadedFaces.get(faceName).getFeaturePointsInfo()
                .stream().collect(Collectors.toList());
            return featurePoints;
        }

        return featurePoints;
    }
    
    /**
     * Loads feature points to combo-box or disable feature points if face 
     * has not any
     * @param faceName String name of face
     */
    private void loadFeaturePoints(String faceName) {
        DefaultComboBoxModel model = new DefaultComboBoxModel();
        if (faceName != null && 
                loadedFaces.get(faceName) != null && 
                !loadedFaces.get(faceName).getFeaturePointsInfo().isEmpty()) {
            
            fpLabel.setEnabled(true);
            jComboBox1.setVisible(true);
                
        } else {
            fpLabel.setEnabled(false);
            jComboBox1.setVisible(false);
        if (faceName != null) {
            model.addAll(getFeaturePoints(faceName));
        
        jComboBox1.setModel(model);
     * Store face geometry info to loadedFaces
     * @param face HumanFace
     */
    public void loadFaceGeometryInfo(HumanFace face) {
        String vertices = Long.toString(face.getMeshModel().getNumVertices());
        String facets = Integer.toString(face.getMeshModel().getFacets().size());
        List<String> featurePoints = face.getFeaturePoints().stream()
                .map(fp -> fp.getFeaturePointType().getName())
                .collect(Collectors.toList());
        
        FaceGeometryInfo faceGeometryInfo = new FaceGeometryInfo(vertices, facets, featurePoints);
        
        loadedFaces.put(face.getShortName(), faceGeometryInfo);
     * Removes face from loadedFaces
     * @param faceName String name of face
    public void removeFaceByName(String faceName) {
        loadedFaces.remove(faceName);
    }
    
    /**
     * Removes all loaded faces
     */
    public void clearLoadedFaces() {
        loadedFaces.clear();
    
    /**
     * Face from list is (de)selected
     * @param selected true if face is selected, false if deselected
     * @param faceNames String name of face
     * @param path Path to face
     */
    public void newSelection(boolean selected, String faceName, Path path) {
            this.showFaceState(faceName, path);
            this.showFaceState(null, null);
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel facetsLabel;
    private javax.swing.JLabel facetsOutput;
Matej Kovár's avatar
Matej Kovár committed
    private javax.swing.JLabel featurePointsLabel;
    private javax.swing.JLabel featurePointsOutput;
    private javax.swing.JPanel filePanel;
    private javax.swing.JLabel fpLabel;
    private javax.swing.JPanel geometryPanel;
    private javax.swing.JComboBox<String> jComboBox1;
    private javax.swing.JButton loadInfoButton;
    private javax.swing.JLabel pathLabel;
    private javax.swing.JLabel pathOutput;
    private javax.swing.JLabel photo;
    private javax.swing.JPanel photoPanel;
Matej Kovár's avatar
Matej Kovár committed
    private javax.swing.JLabel previewLabel;
    private javax.swing.JLabel previewOutput;
    private javax.swing.JLabel sizeLabel;
    private javax.swing.JLabel sizeOutput;
Matej Kovár's avatar
Matej Kovár committed
    private javax.swing.JLabel textureLabel;
    private javax.swing.JLabel textureOutput;
    private javax.swing.JLabel verticesLabel;
    private javax.swing.JLabel verticesOutput;
    // End of variables declaration//GEN-END:variables

}