diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java index 372081f6965e898a409d88b8962c69724026613d..186d429cec9e952caa8a09320bff7cbd17a23a41 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/CrossSection.java @@ -36,7 +36,7 @@ public class CrossSection extends MeshVisitor { Point3d last = null; for (MeshTriangle tri : facet) { if (tri.checkIntersectionWithPlane(plane)) { - Point3d p = facet.getVertex(tri.index1).getPosition(); + Point3d p = tri.getVertex1(); // Check for duplicates if (last != null) { diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/PolylinePanel.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/PolylinePanel.java index 720dc57650a1277bbafd73b22cf72079251bd30b..72b8b8be169bd6846a0092b9c217fc366034f795 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/PolylinePanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/PolylinePanel.java @@ -28,6 +28,8 @@ public class PolylinePanel extends JPanel { private static final Stroke GRAPH_STROKE = new BasicStroke(3f); private List<Point3d> primary; private List<Point3d> secondary; + private boolean alignProfiles = false; + private double primaryOffsetZ = 0; private double scale = Double.POSITIVE_INFINITY; @@ -95,11 +97,15 @@ public class PolylinePanel extends JPanel { } //only calculate scale for the first face and use it for the second as well - if (isPrimary) { + if (scale == Double.POSITIVE_INFINITY) { scale = ((double) PREF_H - 2 * BORDER_GAP) / (maxY - minY); } - double offsetZ = (PREF_W * 0.7) - (maxZ * scale); + if (isPrimary) { + this.primaryOffsetZ = (PREF_W * 0.7) - (maxZ * scale); + } + + double offsetZ = this.alignProfiles ? (PREF_W * 0.7) - (maxZ * scale) : this.primaryOffsetZ; //Draw lines g2.setColor(faceColor); @@ -127,6 +133,38 @@ public class PolylinePanel extends JPanel { } + /** + * Sets primary points and draws them in the panel + * + * @param points primary points + */ + public void setPrimaryPoints(List<Point3d> points) { + this.primary = points; + Collections.sort(this.primary, new CompareY()); + repaint(); + } + + /** + * Sets secondary points and draws them in the panel + * + * @param points secondary points + */ + public void setSecondaryPoints(List<Point3d> points) { + this.secondary = points; + Collections.sort(this.secondary, new CompareY()); + repaint(); + } + + /** + * Aligns the drawn faces in the panel + * + * @param align + */ + public void setAlignProfiles(boolean align) { + this.alignProfiles = align; + repaint(); + } + @Override public Dimension getPreferredSize() { return new Dimension(PREF_W, PREF_H); diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java index 79f57fccecb381b0beddad2a9976d5a483d922bb..4400557ccc2a36e6c3ee8e940b0656abb8b08e50 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesAction.java @@ -44,14 +44,10 @@ public class ProfilesAction extends ControlPanelAction { super(canvas, topControlPanel); this.topControlPanel = topControlPanel; - CrossSection cs1 = new CrossSection(getScene().getDrawableCuttingPlane(0).getFacets().get(0)); - getPrimaryDrawableFace().getModel().compute(cs1); - this.primaryPoints = cs1.getPoints(); + recomputePrimaryProfile(); if (getSecondaryDrawableFace() != null) { - CrossSection cs2 = new CrossSection(getScene().getDrawableCuttingPlane(1).getFacets().get(0)); - getSecondaryDrawableFace().getModel().compute(cs2); - this.secondaryPoints = cs2.getPoints(); + recomputeSecondaryProfile(); controlPanel = new ProfilesPanel(this, this.primaryPoints, this.secondaryPoints); } else { @@ -64,7 +60,10 @@ public class ProfilesAction extends ControlPanelAction { // If the symmetry panel is focused... if (((JTabbedPane) e.getSource()).getSelectedComponent() instanceof ProfilesPanel) { getCanvas().getScene().setDefaultColors(); - getCanvas().getScene().showCuttingPlanes(); + + if (controlPanel.isShowPlaneChecked()) { + getCanvas().getScene().showCuttingPlanes(); + } } else { getCanvas().getScene().hideCuttingPlanes(); } @@ -108,6 +107,24 @@ public class ProfilesAction extends ControlPanelAction { } } + void recomputePrimaryProfile() { + CrossSection cs1 = new CrossSection(getScene().getDrawableCuttingPlane(0).getFacets().get(0)); + getPrimaryDrawableFace().getModel().compute(cs1); + this.primaryPoints = cs1.getPoints(); + } + + void recomputeSecondaryProfile() { + CrossSection cs = new CrossSection(getScene().getDrawableCuttingPlane(1).getFacets().get(0)); + getSecondaryDrawableFace().getModel().compute(cs); + this.secondaryPoints = cs.getPoints(); + } + + void setCuttingPlaneOffset(int index, double value) { + for (int i = 0; i < 4; ++i) { + getScene().getDrawableCuttingPlane(index).getFacets().get(0).getVertex(i).getPosition().x = value; + } + } + @Override public void actionPerformed(ActionEvent ae) { String action = ae.getActionCommand(); @@ -126,6 +143,29 @@ public class ProfilesAction extends ControlPanelAction { exportProfile(this.secondaryPoints, "Export secondary face profile to file"); } break; + case ProfilesPanel.ACTION_OFFSET_CUTTING_PLANE: + double value = Double.parseDouble(controlPanel.getOffsetValue()); + double multiplier = 150; + + setCuttingPlaneOffset(0, multiplier * (value - 0.5)); + + //TODO translation needs to be done differently, maybe recalculate upon change + if (getSecondaryDrawableFace() != null) { + setCuttingPlaneOffset(1, multiplier * (value - 0.5)); + } + break; + case ProfilesPanel.ACTION_COMMAND_RECOMPUTE: + recomputePrimaryProfile(); + controlPanel.setPrimaryPoints(this.primaryPoints); + + if (getSecondaryDrawableFace() != null){ + recomputeSecondaryProfile(); + controlPanel.setSecondaryPoints(this.secondaryPoints); + } + break; + case ProfilesPanel.ACTION_ALIGN_PROFILES: + controlPanel.setAlignProfiles(); + break; default: // do nothing } diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesPanel.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesPanel.java index b44821a7477c1529f98e7ef1d9bd0e07e0a63c06..b5912fde6cafaf75deb8c57b65d9c879edf55f90 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesPanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/ProfilesPanel.java @@ -22,9 +22,10 @@ public class ProfilesPanel extends ControlPanel { /* * GUI primitives holding the configuration state: */ - private JTextField cuttingOffset = null; - private JCheckBox allignFaces; + private JTextField cuttingOffset; + private JCheckBox alignProfiles; private JCheckBox showCuttingPlane; + private PolylinePanel polylinePanel; /* * Handled actions @@ -32,6 +33,8 @@ public class ProfilesPanel extends ControlPanel { public static final String ACTION_COMMAND_SHOW_HIDE_PLANE = "show-hide symmetry plane"; public static final String ACTION_COMMAND_RECOMPUTE = "recompute"; public static final String ACTION_COMMAND_EXPORT = "export"; + public static final String ACTION_OFFSET_CUTTING_PLANE = "offset_plane"; + public static final String ACTION_ALIGN_PROFILES = "align_profiles"; /* * Mandatory design elements @@ -46,8 +49,9 @@ public class ProfilesPanel extends ControlPanel { setName(NAME); ControlPanelBuilder builder = new ControlPanelBuilder(this); + this.polylinePanel = new PolylinePanel(values); - builder.addPolylinePanel(new PolylinePanel(values)); + builder.addPolylinePanel(this.polylinePanel); builder.addLine(); buildPanel(action, builder); @@ -60,8 +64,9 @@ public class ProfilesPanel extends ControlPanel { setName(NAME); ControlPanelBuilder builder = new ControlPanelBuilder(this); + this.polylinePanel = new PolylinePanel(primary, secondary); - builder.addPolylinePanel(new PolylinePanel(primary, secondary)); + builder.addPolylinePanel(this.polylinePanel); builder.addLine(); buildPanel(action, builder); @@ -78,15 +83,19 @@ public class ProfilesPanel extends ControlPanel { "Cutting Plane Offset", -1, (ActionEvent e) -> { - + action.actionPerformed(new ActionEvent( + e.getSource(), + ActionEvent.ACTION_PERFORMED, + ACTION_OFFSET_CUTTING_PLANE + )); }); builder.addLine(); - allignFaces = builder.addCheckBoxOptionLine( + alignProfiles = builder.addCheckBoxOptionLine( null, - "Allign faces", - true, - null + "Align profiles", + false, + createListener(action, ACTION_ALIGN_PROFILES) ); builder.addLine(); @@ -103,10 +112,14 @@ public class ProfilesPanel extends ControlPanel { builder.addButtons( List.of("Recompute", - "Export Profiles"), + "Export Profile(s)"), List.of( (ActionEvent e) -> { - + action.actionPerformed(new ActionEvent( + e.getSource(), + ActionEvent.ACTION_PERFORMED, + ACTION_COMMAND_RECOMPUTE + )); }, (ActionEvent e) -> { action.actionPerformed(new ActionEvent( @@ -142,4 +155,37 @@ public class ProfilesPanel extends ControlPanel { ); } + public boolean isShowPlaneChecked() { + return showCuttingPlane.isSelected(); + } + + public String getOffsetValue() { + return cuttingOffset.getText(); + } + + /** + * Sets the alignProfiles boolean based on the checkbox + */ + public void setAlignProfiles() { + this.polylinePanel.setAlignProfiles(alignProfiles.isSelected()); + } + + /** + * Sets the primary points in the polyline panel + * + * @param points primary points + */ + public void setPrimaryPoints(List<Point3d> points) { + this.polylinePanel.setPrimaryPoints(points); + } + + /** + * Sets the secondary points in the polyline panel + * + * @param points secondary points + */ + public void setSecondaryPoints(List<Point3d> points) { + this.polylinePanel.setSecondaryPoints(points); + } + } diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java index 4ac7291021227e176f5037593dc264b4127050df..19e0de3a6530e203fa9c35bf989d9ad343f52f39 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryAction.java @@ -36,7 +36,7 @@ public class SymmetryAction extends ControlPanelAction { if (((JTabbedPane) e.getSource()).getSelectedComponent() instanceof SymmetryPanel) { getCanvas().getScene().setDefaultColors(); - if (controlPanel.showSymmetryPlane.isSelected()) { + if (controlPanel.isShowPlaneChecked()) { getCanvas().getScene().showSymmetryPlanes(); } } else { diff --git a/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryPanel.java b/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryPanel.java index 7bb0fae215be41deee022487200e2ed2477d83ce..def49c9e3e944409573de104e689523b8f3678f2 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryPanel.java +++ b/GUI/src/main/java/cz/fidentis/analyst/symmetry/SymmetryPanel.java @@ -53,7 +53,7 @@ public final class SymmetryPanel extends ControlPanel { private JTextField minNormAngleCosTF = null; private JTextField maxRelDistTF = null; private final JCheckBox averaging; - public final JCheckBox showSymmetryPlane; + private final JCheckBox showSymmetryPlane; /** * Constructor. @@ -293,4 +293,8 @@ public final class SymmetryPanel extends ControlPanel { new ImageIcon(getClass().getResource("/distance.png")) ); } + + public boolean isShowPlaneChecked() { + return showSymmetryPlane.isSelected(); + } } diff --git a/GUI/src/main/java/cz/fidentis/analyst/toolbar/RenderingModeAction.java b/GUI/src/main/java/cz/fidentis/analyst/toolbar/RenderingModeAction.java index 8bb8807f28631a72d02a4d373570120fb7dd9dab..0655416a54ce86a6e414fc49f8e44548227d0a5e 100644 --- a/GUI/src/main/java/cz/fidentis/analyst/toolbar/RenderingModeAction.java +++ b/GUI/src/main/java/cz/fidentis/analyst/toolbar/RenderingModeAction.java @@ -73,12 +73,10 @@ public class RenderingModeAction extends AbstractAction { break; case ACTION_COMMAND_SHOW_HIDE_PRIMARY_FACE: showHideFace(0, ((JToggleButton) ae.getSource()).isSelected()); - showHideSymmetryPlane(0, ((JToggleButton) ae.getSource()).isSelected()); break; case ACTION_COMMAND_SHOW_HIDE_SECONDARY_FACES: for (int i = 1; i < canvas.getScene().getNumFaces(); i++) { showHideFace(i, ((JToggleButton) ae.getSource()).isSelected()); - showHideSymmetryPlane(i, ((JToggleButton) ae.getSource()).isSelected()); } break; case ACTION_COMMAND_SHOW_HIDE_FEATURE_POINTS: