/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bs.bs2d.gui.plot;
import bs.bs2d.fea.Node2D;
import bs.bs2d.fea.TriMesh2D;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
/**
* Container class for a 2D Tri-Mesh that supports plotting.
* @author Djen
*/
public class MeshPlotter implements Plottable, Selectable{
public static final Color LINE_COLOR = Color.BLACK;
public static final Color BODY_COLOR = Color.GREEN;
public static final Color SELECTION_COLOR = Color.RED;
private final TriMesh2D mesh;
private final Shape outlines;
private final Shape wireframe;
private final HashSet<Node2D> selection;
private boolean showWireframe;
private boolean showSolidELements;
private boolean showNodes;
private boolean showEdgeNodesOnly;
private UpdateListener updateListener;
public MeshPlotter(TriMesh2D mesh){
this.mesh = mesh;
outlines = mesh.createOutlinePath();
wireframe = mesh.createWireframePath();
selection = new HashSet<>();
showWireframe = true;
showNodes = true;
showEdgeNodesOnly = true;
showSolidELements = true;
}
@Override
public Rectangle2D getBounds() {
return outlines.getBounds2D();
}
@Override
public void paint(Graphics2D g, AffineTransform transform) {
Shape tOutlines = transform.createTransformedShape(outlines);
if(showSolidELements){
g.setColor(BODY_COLOR);
g.fill(tOutlines);
}
g.setColor(LINE_COLOR);
g.draw(tOutlines);
if(showWireframe)
g.draw(transform.createTransformedShape(wireframe));
if (showNodes) {
List<Node2D> nodes = mesh.getNodes();
for (Node2D n : nodes) {
// skip inner nodes
if (showEdgeNodesOnly && !n.isOuter())
continue;
// get transformed node location
Point2D p = n.getPoint();
transform.transform(p, p);
if(selection.contains(n))
g.setColor(SELECTION_COLOR);
else
g.setColor(LINE_COLOR);
g.fillRect((int) p.getX() - 3, (int) p.getY() - 3, 7, 7);
}
}
}
@Override
public boolean hasLegend() {
return false;
}
@Override
public Rectangle2D getLegendBounds() {
return null;
}
@Override
public void paintLegend(Graphics2D g) {
// no legend
}
@Override
public void addSelection(Rectangle2D area) {
List<Node2D> nodes = mesh.getNodes();
for (Node2D n : nodes) {
// filter edge nodes
if(showEdgeNodesOnly && !n.isOuter())
continue;
if (area.contains(n.getPoint()))
selection.add(n);
}
selectionChanged();
}
@Override
public void setSelection(Rectangle2D area) {
selection.clear();
addSelection(area);
}
/**
* Sets the selection to the given set of nodes.
* @param nodes a collection of nodes to set as selected
*/
public void setSelection(Collection<Node2D> nodes){
selection.clear();
selection.addAll(nodes);
selectionChanged();
}
@Override
public void removeSelection(Rectangle2D area) {
// remove all nodes contained in area
List<Node2D> nodes = mesh.getNodes();
for (Node2D n : nodes) {
// filter edge nodes
if(showEdgeNodesOnly && !n.isOuter())
continue;
if (area.contains(n.getPoint()))
selection.remove(n);
}
selectionChanged();
}
@Override
public void clearSelection() {
if(!selection.isEmpty()){
selection.clear();
selectionChanged();
}
}
private void selectionChanged() {
String info;
if (selection.isEmpty()) {
info = " - nothing selected - ";
} else if (selection.size() == 1) {
Node2D n = selection.iterator().next();
info = String.format("Node %5d: [ %6.3f | %6.3f ]",
n.getIndex(), n.getX(), n.getY());
} else {
info = selection.size() + " Nodes";
}
update(info);
}
@Override
public void setUpdateListener(UpdateListener ul) {
updateListener = ul;
}
/**
* @param showWireframe set true to display meshes as wireframes
*/
public void setShowWireframe(boolean showWireframe) {
this.showWireframe = showWireframe;
update(null);
}
/**
* @param showNodes set true to show nodes
*/
public void setShowNodes(boolean showNodes) {
this.showNodes = showNodes;
update(null);
}
/**
* @param showEdgeNodesOnly set true to only show edge nodes
*/
public void setShowEdgeNodesOnly(boolean showEdgeNodesOnly) {
this.showEdgeNodesOnly = showEdgeNodesOnly;
update(null);
}
/**
* @param showSolidElements set true to fill elements with solid color
*/
public void setShowSolidElements(boolean showSolidElements) {
this.showSolidELements = showSolidElements;
update(null);
}
private void update(String info){
if(updateListener != null)
updateListener.update(info);
}
/**
* @return the set of selected nodes
*/
public HashSet<Node2D> getSelection() {
return new HashSet<>(selection);
}
}