Commit eb80e08b authored by Robert Smith's avatar Robert Smith
Browse files

Various Mesh Editor fixes



Added various features/bug fixes for the mesh editor, including setting
the meshes' coordinates to line up with the grid, requiring confirmation
for a polygon after its last vertex is added, added more keys for user
interaction, and a bug regarding drawing an edge after an identical edge
had been canceled. 
Signed-off-by: Robert Smith's avatarRobert Smith <SmithRW@ornl.gov>
parent 10770a1f
......@@ -172,7 +172,6 @@ public class FXMeshCanvas extends FXVizCanvas implements IMeshVizCanvas {
root.removeEntity(polygon);
}
}
}
/*
......
......@@ -18,6 +18,7 @@ import org.eclipse.ice.viz.service.javafx.canvas.FXViewer;
import org.eclipse.ice.viz.service.javafx.internal.model.FXCameraAttachment;
import org.eclipse.ice.viz.service.javafx.internal.scene.camera.TopDownCameraController;
import org.eclipse.ice.viz.service.javafx.mesh.datatypes.FXMeshControllerFactory;
import org.eclipse.ice.viz.service.javafx.mesh.datatypes.FXVertexController;
import org.eclipse.ice.viz.service.javafx.scene.base.ICamera;
import org.eclipse.ice.viz.service.mesh.datastructures.NekPolygonController;
import org.eclipse.ice.viz.service.mesh.datastructures.NekPolygonMesh;
......@@ -228,6 +229,7 @@ public class FXMeshViewer extends FXViewer {
}
};
// Create the handler for edit mode dragging
editDragHandler = new EventHandler<MouseEvent>() {
@Override
......@@ -236,6 +238,7 @@ public class FXMeshViewer extends FXViewer {
}
};
// Create the handler for edit mode releasing the mouse button
editMouseUpHandler = new EventHandler<MouseEvent>() {
@Override
......@@ -245,6 +248,7 @@ public class FXMeshViewer extends FXViewer {
};
// Create the handler for moving the mouse
scene.setOnMouseMoved(new EventHandler<MouseEvent>() {
@Override
......@@ -272,13 +276,55 @@ public class FXMeshViewer extends FXViewer {
@Override
public void handle(KeyEvent event) {
// If Escape is pressed, any polygon under construction will be
// If Escape or Backspace is pressed, any polygon under
// construction will be
// removed
if (event.getCode() == KeyCode.ESCAPE) {
if (event.getCode() == KeyCode.ESCAPE
|| event.getCode() == KeyCode.BACK_SPACE) {
clearSelection();
}
// If Delete is pressed remove the currently selected polygons
else if (event.getCode() == KeyCode.DELETE) {
// Check each polygon in the mesh to see if it should be
// deleted
for (AbstractController polygon : ((FXAttachment) attachmentManager
.getAttachments().get(1)).getKnownParts().get(0)
.getEntities()) {
// Whether or not the polygon is completely selected
boolean selected = true;
// Check each of the polygon's vertices
for (AbstractController vertex : polygon
.getEntitiesByCategory("Vertices")) {
// If any vertex is not selected, stop and move on
// to the next
// polygon
if (!"True"
.equals(vertex.getProperty("Selected"))) {
selected = false;
break;
}
}
// If all the vertices were selected, remove the polygon
// from the
// mesh
if (selected) {
((FXAttachment) attachmentManager.getAttachments()
.get(1)).getKnownParts().get(0)
.removeEntity(polygon);
}
}
// Remove any selection
clearSelection();
}
// If another key was pressed, invoke the camera's key handler
else {
handler.handle(event);
......@@ -299,18 +345,61 @@ public class FXMeshViewer extends FXViewer {
// Whether or not a new vertex has been added
boolean changed = false;
// If there are already four vertices already, confirm the addition of
// the polygon
if (selectedVertices.size() == 4) {
// Create a face out of all the edges
NekPolygonMesh faceComponent = new NekPolygonMesh();
NekPolygonController newFace = (NekPolygonController) factory
.createController(faceComponent);
// Set the polygon's name and ID
newFace.setProperty("Name", "Polygon");
newFace.setProperty("Id", String.valueOf(nextPolygonID));
nextPolygonID++;
for (AbstractController edge : tempEdges) {
newFace.addEntityByCategory(edge, "Edges");
// Remove the edge from the temporary root
tempRoot.removeEntity(edge);
}
// Remove the vertices from the temporary root
for (AbstractController vertex : selectedVertices) {
tempRoot.removeEntity(vertex);
}
// Set the new polygon to the default color
newFace.setProperty("Constructing", "False");
// Add the new polygon to the mesh permanently
((FXAttachment) attachmentManager.getAttachments().get(1))
.getKnownParts().get(0).addEntity(newFace);
// Empty the lists of temporary constructs
selectedVertices = new ArrayList<AbstractController>();
tempEdges = new ArrayList<AbstractController>();
return;
}
// If the user didn't select a shape, add a new shape where they
// clicked
if (intersectedNode instanceof Box) {
// Create a new vertex at that point
VertexMesh tempComponent = new VertexMesh(event.getX(),
event.getY(), 0);
// Create a new vertex at that point, divided by SCALE so that the
// internal representation is kept separate from the size things are
// being drawn at
VertexMesh tempComponent = new VertexMesh(event.getX() / SCALE,
event.getY() / SCALE, 0);
tempComponent.setProperty("Constructing", "True");
VertexController tempVertex = (VertexController) factory
FXVertexController tempVertex = (FXVertexController) factory
.createController(tempComponent);
// Set the vertex's name and ID
// Set the vertex's scale, name, and ID
tempVertex.setApplicationScale((int) SCALE);
tempVertex.setProperty("Name", "Vertex");
tempVertex.setProperty("Id", String.valueOf(nextVertexID));
nextVertexID++;
......@@ -384,6 +473,9 @@ public class FXMeshViewer extends FXViewer {
// Add the edge to the list
tempEdges.add(tempEdge);
// Add it to the temp root
tempRoot.addEntity(tempEdge);
// Refresh the edge
tempEdge.refresh();
}
......@@ -397,41 +489,14 @@ public class FXMeshViewer extends FXViewer {
.get(numVertices - 1),
(VertexController) selectedVertices.get(0));
// Add the edge to the list
tempEdges.add(tempEdge);
// Create a face out of all the edges
NekPolygonMesh faceComponent = new NekPolygonMesh();
NekPolygonController newFace = (NekPolygonController) factory
.createController(faceComponent);
// Set the polygon's name and ID
newFace.setProperty("Name", "Polygon");
newFace.setProperty("Id", String.valueOf(nextPolygonID));
nextPolygonID++;
for (AbstractController edge : tempEdges) {
newFace.addEntityByCategory(edge, "Edges");
// Remove the edge from the temporary root
tempRoot.removeEntity(edge);
}
// Remove the vertices from the temporary root
for (AbstractController vertex : selectedVertices) {
tempRoot.removeEntity(vertex);
}
// Set the new polygon to the default color
newFace.setProperty("Constructing", "False");
// Add the new polygon to the mesh permanently
((FXAttachment) attachmentManager.getAttachments().get(1))
.getKnownParts().get(0).addEntity(newFace);
// Empty the lists of temporary constructs
selectedVertices = new ArrayList<AbstractController>();
tempEdges = new ArrayList<AbstractController>();
// Add it to the temp root
tempRoot.addEntity(tempEdge);
// Refresh the edge
tempEdge.refresh();
}
}
}
......@@ -611,9 +676,11 @@ public class FXMeshViewer extends FXViewer {
VertexController vertex = (VertexController) selectedVertices
.get(i);
// Update its position
vertex.updateLocation(relativeXCords.get(i) + mousePosX,
relativeYCords.get(i) + mousePosY, 0);
// Update its position, corected for the scale the editor is
// drawn at
vertex.updateLocation(
(relativeXCords.get(i) + mousePosX) / SCALE,
(relativeYCords.get(i) + mousePosY) / SCALE, 0);
// Remove the markers from the scene
for (Sphere marker : vertexMarkers) {
......@@ -638,10 +705,15 @@ public class FXMeshViewer extends FXViewer {
*/
private void handleMouseMoved(MouseEvent event) {
DecimalFormat format = new DecimalFormat("#.##");
cursorPosition.setText(
"Cursor position (x,y): (" + format.format(event.getX()) + ","
+ format.format(event.getY()) + ")");
cursorPosition.setTranslateZ(-5);
// cursorPosition
// .setText("Cursor position (x,y): ("
// + format.format(event.getPickResult()
// .getIntersectedPoint().getX() / 3)
// + ","
// + event.getPickResult().getIntersectedPoint().getY() / 3
// + ")");
// cursorPosition.setTranslateX(scene.getWidth() / -20);
// cursorPosition.setTranslateZ(-5);
}
/**
......@@ -912,6 +984,9 @@ public class FXMeshViewer extends FXViewer {
defaultCamera = fxCamera;
cursorPosition = new Text();
cursorPosition.setTranslateZ(-5);
internalRoot.getChildren().add(cursorPosition);
}
}
\ No newline at end of file
......@@ -97,12 +97,23 @@ public class FXLinearEdgeView extends AbstractView {
* @return A JavaFX Cylinder representing the given LinearEdgeComponent
*/
private Cylinder createShape(EdgeMesh edgeComponent) {
// Get the scale the vertices are being drawn at
int scale = ((FXVertexController) edgeComponent
.getEntitiesByCategory("Vertices").get(0))
.getApplicationScale();
// Get the edge's endpoints
double[] start = ((org.eclipse.ice.viz.service.modeling.EdgeController) edgeComponent
.getController()).getStartLocation();
double[] end = ((org.eclipse.ice.viz.service.modeling.EdgeController) edgeComponent
.getController()).getEndLocation();
for (int i = 0; i < 3; i++) {
start[i] = start[i] * scale;
end[i] = end[i] * scale;
}
// Create a cylinder situated at the edge's midpoint with the edge's
// length.
Cylinder edge = new Cylinder(.6,
......
......@@ -53,6 +53,28 @@ public class FXVertexController extends VertexController {
.put(AbstractController.class, this);
}
/**
* Get the scale of the application the view is drawn in.
*
* @return The conversion rate between internal units and JavaFX units
*/
public int getApplicationScale() {
return ((FXVertexView) view).getApplicationScale();
}
/**
* Sets the scale of the application this vertex will be displayed in. The
* vertex will now be drawn with all the coordinates in the VertexMesh
* multiplied by the scale.
*
* @param scale
* The conversion factor between JavaFX units and the logical
* units used by the application.
*/
public void setApplicationScale(int scale) {
((FXVertexView) view).setApplicationScale(scale);
}
/*
* (non-Javadoc)
*
......
......@@ -52,6 +52,12 @@ public class FXVertexView extends AbstractView {
*/
private PhongMaterial constructingMaterial;
/**
* The scale of the application the vertex will be displayed in. The vertex
* will be drawn with each coordinate's value multiplied by the scale
*/
private int scale;
/**
* The nullary constructor.
*/
......@@ -60,6 +66,7 @@ public class FXVertexView extends AbstractView {
// Instantiate the class variables
node = new Group();
scale = 1;
// Create the materials
defaultMaterial = new PhongMaterial(Color.rgb(80, 30, 140));
......@@ -95,7 +102,15 @@ public class FXVertexView extends AbstractView {
// Set the sphere to be the constructing material by default
mesh.setMaterial(constructingMaterial);
node.getChildren().add(mesh);
}
/**
* Get the scale of the application the view is drawn in.
*
* @return The conversion rate between internal units and JavaFX units
*/
public int getApplicationScale() {
return scale;
}
/**
......@@ -112,6 +127,23 @@ public class FXVertexView extends AbstractView {
node.getProperties().put(ShapeController.class, mesh);
}
/**
* Sets the scale of the application this vertex will be displayed in. The
* vertex will now be drawn with all the coordinates in the VertexMesh
* multiplied by the scale.
*
* @param scale
* The conversion factor between JavaFX units and the logical
* units used by the application.
*/
public void setApplicationScale(int scale) {
this.scale = scale;
// Notify listeners of the change
SubscriptionType[] eventTypes = { SubscriptionType.PROPERTY };
updateManager.notifyListeners(eventTypes);
}
/*
* (non-Javadoc)
*
......@@ -134,8 +166,8 @@ public class FXVertexView extends AbstractView {
public void refresh(AbstractMesh model) {
// Center the node on the vertex's location
transformation.setTranslation(((VertexMesh) model).getX(),
((VertexMesh) model).getY(), 0);
transformation.setTranslation(((VertexMesh) model).getX() * scale,
((VertexMesh) model).getY() * scale, 0);
// Set the node's transformation
node.getTransforms().setAll(Util.convertTransformation(transformation));
......
......@@ -51,7 +51,7 @@ public class FXViewer extends AbstractViewer {
/**
* The internally used root that cannot be modified by clients.
*/
private Group internalRoot;
protected Group internalRoot;
/** The root of the scene as exposed to clients. */
protected Group root;
......
......@@ -100,13 +100,13 @@ public class TopDownCameraController extends AbstractCameraController {
Point3D xDir = new Point3D(xx, xy, xz).normalize();
// W moves the camera up
if (keyCode == KeyCode.W) {
if (keyCode == KeyCode.W || keyCode == KeyCode.UP) {
Point3D moveVec = yDir.multiply(speed);
affine.appendTranslation(moveVec.getX(), -moveVec.getY(),
moveVec.getZ());
// S moves the camera down
} else if (keyCode == KeyCode.S) {
} else if (keyCode == KeyCode.S || keyCode == KeyCode.DOWN) {
Point3D moveVec = yDir.multiply(speed);
Point3D invVec = new Point3D(-moveVec.getX(), moveVec.getY(),
-moveVec.getZ());
......@@ -114,13 +114,13 @@ public class TopDownCameraController extends AbstractCameraController {
invVec.getZ());
// A moves the camera to the left
} else if (keyCode == KeyCode.A) {
} else if (keyCode == KeyCode.A || keyCode == KeyCode.LEFT) {
Point3D moveVec = xDir.multiply(speed);
affine.appendTranslation(-moveVec.getX(), -moveVec.getY(),
-moveVec.getZ());
// D moves the camera to the right
} else if (keyCode == KeyCode.D) {
} else if (keyCode == KeyCode.D || keyCode == KeyCode.RIGHT) {
Point3D moveVec = xDir.multiply(speed);
affine.appendTranslation(moveVec.getX(), moveVec.getY(),
moveVec.getZ());
......
......@@ -236,7 +236,7 @@ public class AbstractView
.clone();
// Notify own listeners of the change
SubscriptionType[] eventTypes = { SubscriptionType.ALL };
SubscriptionType[] eventTypes = { SubscriptionType.PROPERTY };
updateManager.notifyListeners(eventTypes);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment