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

Face-to-face tab with Hausdorff distance

parent 340bb27c
Loading
Loading
Loading
Loading
+95 −0
Original line number Diff line number Diff line
package cz.fidentis.analyst.core;

import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.toolbar.FaceToFaceToolBar;
import cz.fidentis.analyst.toolbar.RenderingToolBar;
import cz.fidentis.analyst.toolbar.SingleFaceToolBar;
import javax.swing.GroupLayout;
import javax.swing.LayoutStyle;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.windows.TopComponent;

/**
 * The non-singleton window/tab for the analysis of two faces.
 * For the discussion on crating non-singleton top component, 
 * see {@link http://netbeans.apache.org/wiki/DevFaqNonSingletonTopComponents.asciidoc}.
 *
 * @author Radek Oslejsek
 */
@ConvertAsProperties(
        dtd = "-//cz.fidentis.analyst.gui.tab//FaceToFaceTab//EN",
        autostore = false
)
public class FaceToFaceTab extends TopComponent {
    
    public static final int CONTROL_PANEL_WIDTH = 600;
    
    private final Canvas canvas = new Canvas();
    private final FaceToFaceToolBar renderingToolBar;
    private final TopControlPanel controlPanel;

    /**
     * Constructor.
     */
    public FaceToFaceTab() {
        controlPanel = new TopControlPanel();
        renderingToolBar = new FaceToFaceToolBar(canvas, controlPanel);
        initComponents();
    }
    
    @Override
    public int getPersistenceType() {
        return TopComponent.PERSISTENCE_NEVER; // TO DO: change to .PERSISTENCE_ONLY_OPENED when we can re-create the ProjectTC
    }
    
    private void initComponents() {
        GroupLayout layout = new GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(canvas, GroupLayout.DEFAULT_SIZE, 651, Short.MAX_VALUE)
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(renderingToolBar, GroupLayout.PREFERRED_SIZE, RenderingToolBar.WIDTH, GroupLayout.PREFERRED_SIZE)
                                .addComponent(controlPanel, CONTROL_PANEL_WIDTH, CONTROL_PANEL_WIDTH, CONTROL_PANEL_WIDTH)
                        )
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createBaselineGroup(true, true)
                                        .addComponent(canvas)
                                        .addComponent(renderingToolBar)
                                        .addComponent(controlPanel)
                                ))
        );
    }

    @Override
    public void componentOpened() {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed() {
        // TODO add custom code on component closing
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }
    
    public Canvas getCanvas() {
        return canvas;
    }
    
}
+0 −4
Original line number Diff line number Diff line
package cz.fidentis.analyst.core;

import java.awt.Font;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import javax.swing.BorderFactory;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

/**
+1 −1
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ public class CurvaturePanel extends javax.swing.JPanel {
        builder.addCaptionLine("Visualization options:");
        builder.addLine();
        
        builder.addCheckBoxOptionLine(null, "Show symmetry plane", false,
        builder.addCheckBoxOptionLine(null, "Show curvature", false,
                (ActionEvent e) -> {
                    curvAction.actionPerformed(new ActionEvent(
                            e.getSource(), 
+101 −0
Original line number Diff line number Diff line
package cz.fidentis.analyst.distance;

import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.visitors.mesh.HausdorffDistance;
import cz.fidentis.analyst.visitors.mesh.HausdorffDistance.Strategy;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComboBox;
import javax.swing.JTabbedPane;
import javax.swing.JToggleButton;

/**
 * Action listener for the curvature computation.
 * 
 * @author Radek Oslejsek
 */
public class DistanceAction extends AbstractAction {
    
    public static final String ACTION_COMMAND_SHOW_HIDE_PANEL = "show-hide distance control panel";
    public static final String ACTION_COMMAND_SHOW_HIDE_HEATMAP = "show-hide heatmap";
    public static final String ACTION_COMMAND_SET_DISTANCE_STRATEGY = "set strategy";
    public static final String ACTION_COMMAND_RELATIVE_ABSOLUTE_DIST = "switch abosulte-relative distance";
    
    private final DistancePanel controlPanel;
    private final JTabbedPane topControlPanel;
    private final Canvas canvas;
    
    private HausdorffDistance distVisitor = null;
    private String strategy = DistancePanel.STRATEGY_POINT_TO_POINT;
    private boolean relativeDist = false;
    
    /**
     * Constructor.
     * 
     * @param topControlPanel Top component for placing control panels
     * @param canvas OpenGL canvas
     */
    public DistanceAction(JTabbedPane topControlPanel, Canvas canvas) {
        this.canvas = canvas;
        this.controlPanel = new DistancePanel(this);
        this.topControlPanel = topControlPanel;
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        String action = ae.getActionCommand();
        
        switch (action) {
            case ACTION_COMMAND_SHOW_HIDE_PANEL:
                if (((JToggleButton) ae.getSource()).isSelected()) {
                    topControlPanel.addTab(DistancePanel.NAME, DistancePanel.ICON, controlPanel);
                    topControlPanel.setSelectedComponent(controlPanel); // focus
                } else {
                    topControlPanel.remove(controlPanel);
                }
                break;
            case ACTION_COMMAND_SHOW_HIDE_HEATMAP:
                if (((JToggleButton) ae.getSource()).isSelected()) {
                    setHeatmap();
                    canvas.getScene().getDrawableFace(1).setRenderHeatmap(true);
                } else {
                    canvas.getScene().getDrawableFace(1).setRenderHeatmap(false);
                }
                break;
            case ACTION_COMMAND_SET_DISTANCE_STRATEGY:
                strategy = (String) ((JComboBox) ae.getSource()).getSelectedItem();
                this.distVisitor = null; // recompute
                setHeatmap();
                break;
            case ACTION_COMMAND_RELATIVE_ABSOLUTE_DIST:
                this.relativeDist = ((JToggleButton) ae.getSource()).isSelected();
                this.distVisitor = null; // recompute
                setHeatmap();
                break;
            default:
                throw new UnsupportedOperationException(action);
        }
        canvas.renderScene();
    }
    
    protected void setHeatmap() {
        Strategy useStrategy;
        switch (strategy) {
            case DistancePanel.STRATEGY_POINT_TO_POINT:
                useStrategy = Strategy.POINT_TO_POINT;
                break;
            case DistancePanel.STRATEGY_POINT_TO_TRIANGLE:
                useStrategy = Strategy.POINT_TO_TRIANGLE_APPROXIMATE;
                break;
            default:
                throw new UnsupportedOperationException(strategy);
        }
        
        if (distVisitor == null) { 
            this.distVisitor = new HausdorffDistance(canvas.getScene().getDrawableFace(0).getModel(), useStrategy, relativeDist, true);
            canvas.getScene().getDrawableFace(1).getModel().compute(distVisitor);
        }
        
        canvas.getScene().getDrawableFace(1).setHeatMap(distVisitor.getDistances());
    }
}
+63 −0
Original line number Diff line number Diff line
package cz.fidentis.analyst.distance;

import cz.fidentis.analyst.core.ControlPanelBuilder;
import java.awt.event.ActionEvent;
import java.util.List;
import javax.swing.ImageIcon;

/**
 * Control panel for Hausdorff distance.https://www.google.com/#
 * 
 * @author Radek Oslejsek
 */
public class DistancePanel extends javax.swing.JPanel {
    
    public static final ImageIcon ICON = new ImageIcon(DistancePanel.class.getClassLoader().getResource("/distance28x28.png"));
    public static final String NAME = "Hausdorff distance";
    
    public static final String  STRATEGY_POINT_TO_POINT= "Point to point";
    public static final String  STRATEGY_POINT_TO_TRIANGLE= "Point to triangle";
    
    public DistancePanel(DistanceAction action) {
        ControlPanelBuilder builder = new ControlPanelBuilder(this);
        
        builder.addCaptionLine("Computation options:");
        builder.addLine();
        
        builder.addCheckBoxOptionLine(null, "Relative distance", false,
                (ActionEvent e) -> {
                    action.actionPerformed(new ActionEvent(
                            e.getSource(), 
                            ActionEvent.ACTION_PERFORMED, 
                            DistanceAction.ACTION_COMMAND_RELATIVE_ABSOLUTE_DIST)
                    ); 
                });
        builder.addLine();
        
        builder.addOptionText("Distance strategy");
        builder.addComboBox(List.of(STRATEGY_POINT_TO_POINT, STRATEGY_POINT_TO_TRIANGLE),
                (ActionEvent e) -> {                    
                    action.actionPerformed(new ActionEvent(
                            e.getSource(), 
                            ActionEvent.ACTION_PERFORMED, 
                            DistanceAction.ACTION_COMMAND_SET_DISTANCE_STRATEGY)
                    ); 
                });
        builder.addGap();
        builder.addLine();
        
        builder.addCaptionLine("Visualization options:");
        builder.addLine();
        builder.addCheckBoxOptionLine(null, "Show Hausdorff distance", false,
                (ActionEvent e) -> {
                    action.actionPerformed(new ActionEvent(
                            e.getSource(), 
                            ActionEvent.ACTION_PERFORMED, 
                            DistanceAction.ACTION_COMMAND_SHOW_HIDE_HEATMAP)
                    ); 
                });
        builder.addLine();
        builder.addVerticalStrut();
    }
    
}
Loading