Skip to content
Snippets Groups Projects
Commit 610bcda4 authored by Radek Ošlejšek's avatar Radek Ošlejšek
Browse files

Basic functional curvature panel

parent 82c73c70
No related branches found
No related tags found
No related merge requests found
...@@ -134,7 +134,7 @@ public class ControlPanelBuilder { ...@@ -134,7 +134,7 @@ public class ControlPanelBuilder {
JLabel label = new JLabel(caption); JLabel label = new JLabel(caption);
label.setFont(CAPTION_FONT); label.setFont(CAPTION_FONT);
controlPanel.add(label, c); controlPanel.add(label, c);
addLine(); //addLine();
return label; return label;
} }
...@@ -179,7 +179,7 @@ public class ControlPanelBuilder { ...@@ -179,7 +179,7 @@ public class ControlPanelBuilder {
input.setText("0"); input.setText("0");
input.addActionListener(inputAction); input.addActionListener(inputAction);
addSliderWithVal(sliderMax, input); addSliderWithVal(sliderMax, input);
addLine(); //addLine();
return input; return input;
} }
...@@ -200,7 +200,7 @@ public class ControlPanelBuilder { ...@@ -200,7 +200,7 @@ public class ControlPanelBuilder {
} }
addOptionText((text == null) ? "" : text); addOptionText((text == null) ? "" : text);
JCheckBox cb = addCheckBox(selected, checkBoxAction); JCheckBox cb = addCheckBox(selected, checkBoxAction);
addLine(); //addLine();
return cb; return cb;
} }
......
package cz.fidentis.analyst.curvature; package cz.fidentis.analyst.curvature;
import cz.fidentis.analyst.canvas.Canvas; import cz.fidentis.analyst.canvas.Canvas;
import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.visitors.mesh.Curvature; import cz.fidentis.analyst.visitors.mesh.Curvature;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
...@@ -16,6 +19,7 @@ import javax.swing.JToggleButton; ...@@ -16,6 +19,7 @@ import javax.swing.JToggleButton;
public class CurvatureAction extends AbstractAction { public class CurvatureAction extends AbstractAction {
public static final String ACTION_COMMAND_SHOW_HIDE_PANEL = "show-hide curvature control panel"; public static final String ACTION_COMMAND_SHOW_HIDE_PANEL = "show-hide curvature control panel";
public static final String ACTION_COMMAND_SHOW_HIDE_HEATMAP = "show-hide heatmap";
private final CurvaturePanel controlPanel; private final CurvaturePanel controlPanel;
private final JTabbedPane topControlPanel; private final JTabbedPane topControlPanel;
...@@ -46,13 +50,22 @@ public class CurvatureAction extends AbstractAction { ...@@ -46,13 +50,22 @@ public class CurvatureAction extends AbstractAction {
if (((JToggleButton) ae.getSource()).isSelected()) { if (((JToggleButton) ae.getSource()).isSelected()) {
topControlPanel.addTab(CurvaturePanel.NAME, CurvaturePanel.ICON, controlPanel); topControlPanel.addTab(CurvaturePanel.NAME, CurvaturePanel.ICON, controlPanel);
topControlPanel.setSelectedComponent(controlPanel); // focus topControlPanel.setSelectedComponent(controlPanel); // focus
if (curvatureVisitor == null) {
//canvas.getScene().getDrawableFace(0).getModel().compute(curvatureVisitor);
}
} else { } else {
topControlPanel.remove(controlPanel); topControlPanel.remove(controlPanel);
} }
break; break;
case ACTION_COMMAND_SHOW_HIDE_HEATMAP:
if (((JToggleButton) ae.getSource()).isSelected()) {
if (curvatureVisitor == null) { // compute missing curvature
this.curvatureVisitor = new Curvature();
canvas.getScene().getDrawableFace(0).getModel().compute(curvatureVisitor);
canvas.getScene().getDrawableFace(0).setHeatMap(curvatureVisitor.getGaussianCurvatures());
}
canvas.getScene().getDrawableFace(0).setRenderHeatmap(true);
} else {
canvas.getScene().getDrawableFace(0).setRenderHeatmap(false);
}
break;
default: default:
throw new UnsupportedOperationException(action); throw new UnsupportedOperationException(action);
} }
......
package cz.fidentis.analyst.curvature; package cz.fidentis.analyst.curvature;
import cz.fidentis.analyst.core.ControlPanelBuilder; import cz.fidentis.analyst.core.ControlPanelBuilder;
import java.awt.event.ActionEvent;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
/** /**
...@@ -13,9 +14,23 @@ public class CurvaturePanel extends javax.swing.JPanel { ...@@ -13,9 +14,23 @@ public class CurvaturePanel extends javax.swing.JPanel {
public static final ImageIcon ICON = new ImageIcon(CurvaturePanel.class.getClassLoader().getResource("/curvature28x28.png")); public static final ImageIcon ICON = new ImageIcon(CurvaturePanel.class.getClassLoader().getResource("/curvature28x28.png"));
public static final String NAME = "Curvature"; public static final String NAME = "Curvature";
//private final JCheckBox showCurvature;
public CurvaturePanel(CurvatureAction curvAction) { public CurvaturePanel(CurvatureAction curvAction) {
new ControlPanelBuilder(this) ControlPanelBuilder builder = new ControlPanelBuilder(this);
.addCaptionLine("TO DO");
builder.addCaptionLine("Visualization options:");
builder.addLine();
builder.addCheckBoxOptionLine(null, "Show symmetry plane", false,
(ActionEvent e) -> {
curvAction.actionPerformed(new ActionEvent(
e.getSource(),
ActionEvent.ACTION_PERFORMED,
CurvatureAction.ACTION_COMMAND_SHOW_HIDE_HEATMAP)
);
});
builder.addLine();
} }
} }
package cz.fidentis.analyst.scene; package cz.fidentis.analyst.scene;
import com.jogamp.opengl.GL2;
import cz.fidentis.analyst.feature.FeaturePoint; import cz.fidentis.analyst.feature.FeaturePoint;
import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.mesh.core.MeshModel; import cz.fidentis.analyst.mesh.core.MeshModel;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Drawable human face. * Drawable human face.
...@@ -19,6 +24,12 @@ public class DrawableFace extends DrawableMesh { ...@@ -19,6 +24,12 @@ public class DrawableFace extends DrawableMesh {
private List<FeaturePoint> featurePoints = new ArrayList<>(); private List<FeaturePoint> featurePoints = new ArrayList<>();
private List<Color> featurePointsColor = new ArrayList<>(); private List<Color> featurePointsColor = new ArrayList<>();
private boolean renderFeaturePoints = false; private boolean renderFeaturePoints = false;
private boolean renderHeatMap = false;
/**
* Values at mesh vertices that are to be transferred to colors.
*/
private Map<MeshFacet, List<Double>> heatmap = new HashMap<>();
/** /**
* Constructor. * Constructor.
...@@ -74,10 +85,49 @@ public class DrawableFace extends DrawableMesh { ...@@ -74,10 +85,49 @@ public class DrawableFace extends DrawableMesh {
} }
/** /**
* Sets if feature points should be renderred or not * Sets if feature points should be rendered or not
* @param renderFeaturePoints * @param renderFeaturePoints
*/ */
public void setRenderFeaturePoints(boolean renderFeaturePoints) { public void setRenderFeaturePoints(boolean renderFeaturePoints) {
this.renderFeaturePoints = renderFeaturePoints; this.renderFeaturePoints = renderFeaturePoints;
} }
/**
* Sets new heatmap.
*
* @param heatmap New heatmap
*/
public void setHeatMap(Map<MeshFacet, List<Double>> heatmap) {
this.heatmap = heatmap;
}
public Map<MeshFacet, List<Double>> getHeatMap() {
return Collections.unmodifiableMap(heatmap);
}
/**
* Sets if the heatmap should be rendered or not.
* @param render The switch
*/
public void setRenderHeatmap(boolean render) {
this.renderHeatMap = render;
}
/**
* Determines whether the heatmap is set to be rendered.
* @return id the heatmap will be rendered
*/
public boolean isHeatmapRendered() {
return this.renderHeatMap;
}
@Override
protected void renderObject(GL2 gl) {
if (isHeatmapRendered()) {
new HeatmapRenderer().drawMeshModel(gl, getModel(), heatmap);
} else {
super.renderObject(gl);
}
}
} }
...@@ -72,6 +72,7 @@ public class DrawableMesh extends Drawable { ...@@ -72,6 +72,7 @@ public class DrawableMesh extends Drawable {
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, highlights, 0); gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, highlights, 0);
} }
@Override
protected void renderObject(GL2 gl) { protected void renderObject(GL2 gl) {
for (MeshFacet facet: getFacets()) { for (MeshFacet facet: getFacets()) {
gl.glBegin(GL2.GL_TRIANGLES); //vertices are rendered as triangles gl.glBegin(GL2.GL_TRIANGLES); //vertices are rendered as triangles
......
package cz.fidentis.analyst.scene;
import com.jogamp.opengl.GL2;
import cz.fidentis.analyst.mesh.core.MeshFacet;
import cz.fidentis.analyst.mesh.core.MeshModel;
import java.awt.Color;
import java.util.List;
import java.util.Map;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
/**
*
* @author Daniel Sokol
*/
public class HeatmapRenderer {
private Color minColor = Color.RED;
private Color maxColor = Color.BLUE;
public void setMinColor(Color color) {
minColor = color;
}
public void setMaxColor(Color color) {
maxColor = color;
}
public void drawMeshModel(GL2 gl, MeshModel model, Map<MeshFacet, List<Double>> distances) {
Double minDistance = Double.POSITIVE_INFINITY;
Double maxDistance = Double.NEGATIVE_INFINITY;
for (MeshFacet f: model.getFacets()) {
List<Double> distanceList = distances.get(f);
minDistance = Math.min(minDistance, distanceList.parallelStream().mapToDouble(Double::doubleValue).min().getAsDouble());
maxDistance = Math.max(maxDistance, distanceList.parallelStream().mapToDouble(Double::doubleValue).max().getAsDouble());
}
for (MeshFacet f: model.getFacets()) {
renderMeshFacet(gl, f, distances.get(f), minDistance, maxDistance);
}
}
public void renderMeshFacet(GL2 gl, MeshFacet facet, List<Double> distancesList, Double minDistance, Double maxDistance) {
gl.glBegin(GL2.GL_TRIANGLES); //vertices are rendered as triangles
// get the normal and tex coords indicies for face i
for (int v = 0; v < facet.getCornerTable().getSize(); v++) {
// render the normals
Vector3d norm = facet.getVertices().get(facet.getCornerTable().getRow(v).getVertexIndex()).getNormal();
if (norm != null) {
gl.glNormal3d(norm.x, norm.y, norm.z);
}
// render the vertices
Point3d vert = facet.getVertices().get(facet.getCornerTable().getRow(v).getVertexIndex()).getPosition();
//get color of vertex
Color c = getColor(distancesList.get(facet.getCornerTable().getRow(v).getVertexIndex()), minDistance, maxDistance);
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, c.getComponents(null), 0);
gl.glVertex3d(vert.x, vert.y, vert.z);
}
gl.glEnd();
gl.glPopAttrib();
}
private Color getColor(Double currentDistance, Double minDistance, Double maxDistance) {
double currentParameter = ((currentDistance - minDistance) / (maxDistance - minDistance));
float[] hsb1 = Color.RGBtoHSB(minColor.getRed(), minColor.getGreen(), minColor.getBlue(), null);
float h1 = hsb1[0];
float s1 = hsb1[1];
float b1 = hsb1[2];
float[] hsb2 = Color.RGBtoHSB(maxColor.getRed(), maxColor.getGreen(), maxColor.getBlue(), null);
float h2 = hsb2[0];
float s2 = hsb2[1];
float b2 = hsb2[2];
// determine clockwise and counter-clockwise distance between hues
float distCCW;
float distCW;
if (h1 >= h2) {
distCCW = h1 - h2;
distCW = 1 + h2 - h1;
} else {
distCCW = 1 + h1 - h2;
distCW = h2 - h1;
}
float hue;
if (distCW >= distCCW) {
hue = (float) (h1 + (distCW * currentParameter));
} else {
hue = (float) (h1 - (distCCW * currentParameter));
}
if (hue < 0) {
hue = 1 + hue;
}
if (hue > 1) {
hue = hue - 1;
}
float saturation = (float) ((1 - currentParameter) * s1 + currentParameter * s2);
float brightness = (float) ((1 - currentParameter) * b1 + currentParameter * b2);
return Color.getHSBColor(hue, saturation, brightness);
}
}
...@@ -48,6 +48,7 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -48,6 +48,7 @@ public final class SymmetryPanel extends javax.swing.JPanel {
ControlPanelBuilder builder = new ControlPanelBuilder(this); ControlPanelBuilder builder = new ControlPanelBuilder(this);
builder.addCaptionLine("Computation options:"); builder.addCaptionLine("Computation options:");
builder.addLine();
signPointsTF = builder.addSliderOptionLine( signPointsTF = builder.addSliderOptionLine(
(ActionEvent e) -> { (ActionEvent e) -> {
...@@ -59,6 +60,7 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -59,6 +60,7 @@ public final class SymmetryPanel extends javax.swing.JPanel {
tempConfig.setSignificantPointCount(ControlPanelBuilder.parseLocaleInt(signPointsTF)); tempConfig.setSignificantPointCount(ControlPanelBuilder.parseLocaleInt(signPointsTF));
} }
); );
builder.addLine();
minCurvatureTF = builder.addSliderOptionLine( minCurvatureTF = builder.addSliderOptionLine(
(ActionEvent e) -> { (ActionEvent e) -> {
...@@ -69,6 +71,7 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -69,6 +71,7 @@ public final class SymmetryPanel extends javax.swing.JPanel {
(ActionEvent e) -> { (ActionEvent e) -> {
tempConfig.setMinCurvRatio(ControlPanelBuilder.parseLocaleDouble(minCurvatureTF)); tempConfig.setMinCurvRatio(ControlPanelBuilder.parseLocaleDouble(minCurvatureTF));
}); });
builder.addLine();
minAngleCosTF = builder.addSliderOptionLine( minAngleCosTF = builder.addSliderOptionLine(
(ActionEvent e) -> { (ActionEvent e) -> {
...@@ -79,6 +82,7 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -79,6 +82,7 @@ public final class SymmetryPanel extends javax.swing.JPanel {
(ActionEvent e) -> { (ActionEvent e) -> {
tempConfig.setMinAngleCos(ControlPanelBuilder.parseLocaleDouble(minAngleCosTF)); tempConfig.setMinAngleCos(ControlPanelBuilder.parseLocaleDouble(minAngleCosTF));
}); });
builder.addLine();
minNormAngleCosTF = builder.addSliderOptionLine( minNormAngleCosTF = builder.addSliderOptionLine(
(ActionEvent e) -> { (ActionEvent e) -> {
...@@ -89,6 +93,7 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -89,6 +93,7 @@ public final class SymmetryPanel extends javax.swing.JPanel {
(ActionEvent e) -> { (ActionEvent e) -> {
tempConfig.setMinNormAngleCos(ControlPanelBuilder.parseLocaleDouble(minNormAngleCosTF)); tempConfig.setMinNormAngleCos(ControlPanelBuilder.parseLocaleDouble(minNormAngleCosTF));
}); });
builder.addLine();
maxRelDistTF = builder.addSliderOptionLine( maxRelDistTF = builder.addSliderOptionLine(
(ActionEvent e) -> { (ActionEvent e) -> {
...@@ -99,13 +104,16 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -99,13 +104,16 @@ public final class SymmetryPanel extends javax.swing.JPanel {
(ActionEvent e) -> { (ActionEvent e) -> {
tempConfig.setMaxRelDistance(ControlPanelBuilder.parseLocaleDouble(maxRelDistTF)); tempConfig.setMaxRelDistance(ControlPanelBuilder.parseLocaleDouble(maxRelDistTF));
}); });
builder.addLine();
averaging = builder.addCheckBoxOptionLine((ActionEvent e) -> { showAveragingHelp(); }, "Averaging", config.isAveraging(), averaging = builder.addCheckBoxOptionLine((ActionEvent e) -> { showAveragingHelp(); }, "Averaging", config.isAveraging(),
(ActionEvent e) -> { (ActionEvent e) -> {
tempConfig.setAveraging(((JToggleButton) e.getSource()).isSelected()); tempConfig.setAveraging(((JToggleButton) e.getSource()).isSelected());
}); });
builder.addLine();
builder.addCaptionLine("Visualization options:"); builder.addCaptionLine("Visualization options:");
builder.addLine();
showSymmetryPlane = builder.addCheckBoxOptionLine(null, "Show symmetry plane", true, showSymmetryPlane = builder.addCheckBoxOptionLine(null, "Show symmetry plane", true,
(ActionEvent e) -> { (ActionEvent e) -> {
...@@ -115,6 +123,7 @@ public final class SymmetryPanel extends javax.swing.JPanel { ...@@ -115,6 +123,7 @@ public final class SymmetryPanel extends javax.swing.JPanel {
SymmetryAction.ACTION_COMMAND_SHOW_HIDE_PLANE) SymmetryAction.ACTION_COMMAND_SHOW_HIDE_PLANE)
); );
}); });
builder.addLine();
builder.addButtons( builder.addButtons(
List.of("Reset changes", List.of("Reset changes",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment