Commit 54edfde4 authored by Robert Smith's avatar Robert Smith
Browse files

Debugging Plant View data types



Fixed issues with Plant View modeling part display in the Geometry
Editor, including pipe angling calculations and junction and reactor
dimension issues.
Signed-off-by: Robert Smith's avatarRobert Smith <SmithRW@ornl.gov>
parent 89642448
......@@ -151,7 +151,7 @@ public class Extrema {
* @return The minimum Y coordinate
*/
public double getMinY() {
return minX;
return minY;
}
/**
......
......@@ -11,7 +11,6 @@
package org.eclipse.ice.viz.service.geometry.reactor;
import org.eclipse.ice.viz.service.modeling.AbstractController;
import org.eclipse.ice.viz.service.modeling.ShapeController;
import org.eclipse.ice.viz.service.modeling.ShapeMesh;
/**
......@@ -41,11 +40,11 @@ public class ReactorMesh extends ShapeMesh {
public void addEntityByCategory(AbstractController entity,
String category) {
// If the entity is a pipe, set this shape as its parent, so
// If the entity is a Core Channel, set this shape as its parent, so
// that when the reactor is transformed all core channels will also be
// transformed
if (entity instanceof PipeController) {
((PipeController) entity).setParent((ShapeController) controller);
if ("Core Channels".equals(category)) {
((PipeController) entity).setParent(controller);
}
super.addEntityByCategory(entity, category);
......
......@@ -118,7 +118,7 @@ public class FXShapeController extends ShapeController
* service.modeling.Shape)
*/
@Override
public void setParent(ShapeController parent) {
public void setParent(AbstractController parent) {
// If the shape already has a parent, remove this shape's JavaFX node
// from the parent's JavaFX node. Ignore this step for the root shape,
......
......@@ -245,6 +245,7 @@ public class FXShapeView extends AbstractView implements IWireFramePart {
if (defaultMaterial == null) {
defaultMaterial = new PhongMaterial(Color.CYAN);
defaultMaterial.setSpecularColor(Color.WHITE);
}
shape.setMaterial(defaultMaterial);
} else {
......
......@@ -91,15 +91,15 @@ public class FXJunctionView extends JunctionView implements IWireFramePart {
// A list of the extrema of all pipe ends
ArrayList<Extrema> pipeEdges = new ArrayList<Extrema>();
// Get the top end of each input pipe
// Get the bottom end of each input pipe
for (AbstractController input : model.getEntitiesByCategory("Input")) {
pipeEdges.add(((PipeController) input).getUpperExtrema());
pipeEdges.add(((PipeController) input).getLowerExtrema());
}
// Get the bottom end of each output pipe
// Get the top end of each output pipe
for (AbstractController output : model
.getEntitiesByCategory("Output")) {
pipeEdges.add(((PipeController) output).getLowerExtrema());
pipeEdges.add(((PipeController) output).getUpperExtrema());
}
// Get the bounds of the region encompassing all pipe ends
......@@ -113,16 +113,18 @@ public class FXJunctionView extends JunctionView implements IWireFramePart {
centerY = Math.max(boxBounds.getMaxY() - boxBounds.getMinY(), 1);
centerZ = Math.max(boxBounds.getMaxZ() - boxBounds.getMinZ(), 1);
System.out.println(
"Junction center:" + centerX + " " + centerY + " " + centerZ);
// Create a box which fills the box bounds
box = new Box(centerX, centerY, centerZ);
// Create a box which fills the box bounds, adding 1 to each dimension
// to give enough space between the meshes that they won't clip through
// each other.
box = new Box(centerX + 1, centerY + 1, centerZ + 1);
// Move the box to the center of the bounded area
box.setTranslateX((boxBounds.getMaxX() + boxBounds.getMinX()) / 2);
box.setTranslateX((boxBounds.getMaxY() + boxBounds.getMinY()) / 2);
box.setTranslateX((boxBounds.getMaxZ() + boxBounds.getMinZ()) / 2);
box.setTranslateX((boxBounds.getMaxX() - boxBounds.getMinX()) / 2
+ boxBounds.getMinX());
box.setTranslateY((boxBounds.getMaxY() - boxBounds.getMinY()) / 2
+ boxBounds.getMinY());
box.setTranslateZ((boxBounds.getMaxZ() - boxBounds.getMinZ()) / 2
+ boxBounds.getMinZ());
// Add the box to the scene and set its material
node.getChildren().add(box);
......
......@@ -34,9 +34,6 @@ public class FXPipeView extends FXShapeView
*/
public FXPipeView() {
super();
defaultMaterial = new PhongMaterial(Color.CYAN);
defaultMaterial.setSpecularColor(Color.WHITE);
}
/**
......@@ -51,12 +48,16 @@ public class FXPipeView extends FXShapeView
// Pipes are cyan by default
if (!"True".equals(model.getProperty("Core Channel"))) {
setMaterial(new PhongMaterial(Color.CYAN));
PhongMaterial material = new PhongMaterial(Color.CYAN);
material.setSpecularColor(Color.WHITE);
setMaterial(material);
}
// Core channels are red
else {
setMaterial(new PhongMaterial(Color.RED));
PhongMaterial material = new PhongMaterial(Color.RED);
material.setSpecularColor(Color.WHITE);
setMaterial(material);
}
}
......@@ -84,7 +85,7 @@ public class FXPipeView extends FXShapeView
public Extrema getUpperExtrema() {
// Get the mesh's lower boundary and calculate its extrema
float[] points = tubeShape.getLowerBoundary();
float[] points = tubeShape.getUpperBoundary();
return calculateExtrema(points);
}
......@@ -98,17 +99,17 @@ public class FXPipeView extends FXShapeView
private Extrema calculateExtrema(float[] points) {
// Get the transformation's parameters
double[] rotationDegrees = transformation.getRotation();
double[] rotation = transformation.getRotation();
double[] scale = transformation.getScale();
double size = transformation.getSize();
double[] skew = transformation.getSkew();
double[] translation = transformation.getTranslation();
// Convert the degrees to radians
double[] rotation = new double[3];
rotation[0] = rotationDegrees[0] * 180 / Math.PI;
rotation[1] = rotationDegrees[1] * 180 / Math.PI;
rotation[2] = rotationDegrees[2] * 180 / Math.PI;
// // Convert the radians to degrees
// double[] rotation = new double[3];
// rotation[0] = rotationRadians[0] * 180 / Math.PI;
// rotation[1] = rotationRadians[1] * 180 / Math.PI;
// rotation[2] = rotationRadians[2] * 180 / Math.PI;
// TODO Apply skew from the transformation
// Consider each point one at a time
......@@ -121,30 +122,30 @@ public class FXPipeView extends FXShapeView
// Apply size and scale to the points
points[i * 3] = (float) (points[i * 3] * size * scale[0]);
points[i * 3 + 1] = (float) (points[i * 3] * size * scale[1]);
points[i * 3 + 2] = (float) (points[i * 3] * size * scale[2]);
points[i * 3 + 1] = (float) (points[i * 3 + 1] * size * scale[1]);
points[i * 3 + 2] = (float) (points[i * 3 + 2] * size * scale[2]);
// Apply the rotation to the point
float x = points[i * 3];
float y = points[i * 3 + 1];
float z = points[i * 3 + 2];
// Rotate about the x axis
float tempY = (float) (y * Math.cos(rotation[0])
- z * Math.sin(rotation[0]));
z = (float) (y * Math.sin(rotation[0]) - z * Math.cos(rotation[0]));
// Rotate about the z axis
float tempY = (float) (x * Math.sin(rotation[2])
+ y * Math.cos(rotation[2]));
x = (float) (x * Math.cos(rotation[2]) - y * Math.sin(rotation[2]));
y = tempY;
// Rotate about the y axis
float tempX = (float) (z * Math.sin(rotation[1])
- x * Math.cos(rotation[1]));
+ x * Math.cos(rotation[1]));
z = (float) (z * Math.cos(rotation[1]) - x * Math.sin(rotation[1]));
x = tempX;
// Rotate about the z axis
tempY = (float) (x * Math.sin(rotation[2])
- y * Math.cos(rotation[2]));
x = (float) (x * Math.cos(rotation[2]) - y * Math.sin(rotation[2]));
// Rotate about the x axis
tempY = (float) (y * Math.cos(rotation[0])
- z * Math.sin(rotation[0]));
z = (float) (y * Math.sin(rotation[0]) + z * Math.cos(rotation[0]));
y = tempY;
// Apply the skew and save the calculated values back to the array
......@@ -154,8 +155,8 @@ public class FXPipeView extends FXShapeView
// Apply translation to each coordinate
points[i * 3] = (float) (points[i * 3] + translation[0]);
points[i * 3 + 1] = (float) (points[i * 3] + translation[1]);
points[i * 3 + 2] = (float) (points[i * 3] + translation[2]);
points[i * 3 + 1] = (float) (points[i * 3 + 1] + translation[1]);
points[i * 3 + 2] = (float) (points[i * 3 + 2] + translation[2]);
}
......@@ -211,12 +212,16 @@ public class FXPipeView extends FXShapeView
// Pipes are cyan by default
if (!"True".equals(model.getProperty("Core Channel"))) {
defaultMaterial = new PhongMaterial(Color.CYAN);
PhongMaterial material = new PhongMaterial(Color.CYAN);
material.setSpecularColor(Color.WHITE);
setMaterial(material);
}
// Core channels are red
else {
defaultMaterial = new PhongMaterial(Color.RED);
PhongMaterial material = new PhongMaterial(Color.RED);
material.setSpecularColor(Color.WHITE);
setMaterial(material);
}
super.refresh(model);
......
......@@ -74,7 +74,7 @@ public class FXPlantCompositeConverter implements IVizUpdateableListener {
* The scale which translates between RELAP7 units and JavaFX units. Each
* RELAP7 unit will be treated as SCALE JavaFX units.
*/
private final int SCALE = 100;
private final int SCALE = 50;
/**
* The root of the tree of plant parts converted from the source.
......@@ -434,7 +434,7 @@ public class FXPlantCompositeConverter implements IVizUpdateableListener {
// Set the pipe as a core channel and add it to the root
pipe.setProperty("Core Channel", "True");
root.addEntityByCategory(pipe, "Core Channels");
root.addEntity(pipe);
}
......@@ -635,37 +635,87 @@ public class FXPlantCompositeConverter implements IVizUpdateableListener {
// half its length in the direction of the orientation vector will
// place the output edge's center on the origin, so that the
// position vector now properly represents the movement from the
// origen to the pipe's position.
// origin to the pipe's position.
double pipeLength = plantComp.getLength() * SCALE;
position[0] += pipeLength / 2 * normalized[0];
position[1] += pipeLength / 2 * normalized[1];
position[2] += pipeLength / 2 * normalized[2];
// System.out.println("Translation: " + position[0] + " " +
// position[1]
// + " " + position[2]);
// Set the pipe's translation
pipe.setTranslation(position[0], position[1], position[2]);
// Calculate the amount of z rotation in the formula, applying none
// if the normalized vector has a 0 X component. This is done to
// avoid division by 0.
// Calculate the amount of radians per axis as follows: (rotation z)
// = atan(y/x) and (rotation y) = atan (z / sqrt(x ^ 2 + y ^ 2))
// Calculate the y rotation angle
double yRotation;
if (normalized[1] != 0 || normalized[0] != 0) {
yRotation = normalized[2] / Math.sqrt(Math.pow(normalized[0], 2)
+ Math.pow(normalized[1], 2));
} else {
yRotation = 0d;
}
// Calculate the z rotation angle
double zRotation;
if (normalized[0] != 0) {
zRotation = normalized[1] / normalized[0] + 90;
zRotation = normalized[1] / normalized[0];
} else {
zRotation = 90d;
zRotation = 0d;
}
// If the pitch and yaw are both zero, then the orientation vector
// is pointing down one of the axes. The code in this case works for
// the x axis and other arbitrary angles.
if ((yRotation != 0 && zRotation != 0) || normalized[0] != 0) {
// Set the rotation, adding a 90 degree rotation on the z axis
// so that the pipe is pointing down the x axis by defualt
pipe.setRotation(0, -Math.atan(yRotation),
-Math.atan(zRotation) - Math.PI / 2);
}
// The normalized orientation vector can be represented by an
// XY-plane angle calculated by arctan(y/x) and an angle from the z
// vector, calculated by arccos(z).
pipe.setRotation(Math.acos(normalized[2] * 180 / Math.PI), 0,
Math.atan(zRotation * 180 / Math.PI));
// Explicitly set the pipe to point down the y or z axis
else {
// Rotate the pipe to point down the z axis by rotating about
// the x
if (normalized[2] > 0) {
pipe.setRotation(Math.PI / 2, 0, 0);
}
// Rotate in the other direction if the vector is negative
else if (normalized[2] < 0) {
pipe.setRotation(Math.PI / 2, 0, 0);
}
// If the orientation is the negated y vector, flip the tube by
// 180 degrees about the x axis to turn it upside down. The
// positive y vector is the tube's default position, and thus
// does not need to be handled.
else if (normalized[1] < 0) {
pipe.setRotation(Math.PI, 0, 0);
}
}
// System.out.println(
// "Rotation: " + normalized[2] + " " + 0 + " " + (zRotation));
//
// // Calculate the amount of z rotation in the formula, applying
// none
// // if the normalized vector has a 0 X component. This is done to
// // avoid division by 0.
// double zRotation;
// if (normalized[0] != 0) {
// zRotation = normalized[1] / normalized[0] + 90;
// } else {
// zRotation = 90d;
// }
//
// // The normalized orientation vector can be represented by an
// // XY-plane angle calculated by arctan(y/x) and an angle from the
// z
// // vector, calculated by arccos(z).
// pipe.setRotation(Math.acos(normalized[2] * 180 / Math.PI), 0,
// Math.atan(zRotation * 180 / Math.PI));
return pipe;
}
......
......@@ -40,6 +40,9 @@ public class FXPlantViewRootController extends AbstractController
*/
public FXPlantViewRootController(AbstractMesh model, AbstractView view) {
super(model, view);
// Identify this object as the root of the tree
model.setProperty("Root", "True");
}
/*
......
......@@ -16,6 +16,7 @@ import org.eclipse.ice.viz.service.geometry.reactor.Extrema;
import org.eclipse.ice.viz.service.geometry.reactor.PipeController;
import org.eclipse.ice.viz.service.geometry.reactor.ReactorMesh;
import org.eclipse.ice.viz.service.modeling.AbstractController;
import org.eclipse.ice.viz.service.modeling.AbstractMesh;
import org.eclipse.ice.viz.service.modeling.AbstractView;
import org.eclipse.ice.viz.service.modeling.IWireFramePart;
......@@ -119,13 +120,11 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
// Check all the reactor's children for core channels
for (AbstractController channel : model.getEntities()) {
if (channel instanceof PipeController) {
if ("True".equals(channel.getProperty("Core Chanel"))) {
if ("True".equals(channel.getProperty("Core Channel"))) {
// Add the extrema of core channels to the list
extrema.add(((PipeController) channel).getLowerExtrema());
extrema.add(((PipeController) channel).getUpperExtrema());
}
// Add the extrema of core channels to the list
extrema.add(((PipeController) channel).getLowerExtrema());
extrema.add(((PipeController) channel).getUpperExtrema());
}
}
......@@ -133,7 +132,7 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
Extrema bounds = new Extrema(extrema);
// How thick the mesh will be
double thickness = 25;
double thickness = 5;
// The number of samples to be used in the creation of the circular
// portion of the mesh
......@@ -149,7 +148,7 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
double sizeY = bounds.getMaxY() - bounds.getMinY();
double sizeZ = bounds.getMaxZ() - bounds.getMinZ();
// Set the characteristics based on the
// Set the characteristics based on the sizes
depth = Math.min(Math.min(sizeX, sizeY), sizeZ);
height = Math.max(Math.max(sizeX, sizeY), sizeZ);
if (sizeX < height && sizeX > depth) {
......@@ -160,12 +159,18 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
width = sizeZ;
}
// Widen the reactor so that the inner wall is touching the bounds of
// the core channels, saving the original width for later comparisons
double origWidth = width;
width = width + thickness;
// The material for the shapes
PhongMaterial material = new PhongMaterial(Color.WHITE);
// Discard the old reactor node
// Discard the old reactor node and replace it with a new one.
node.getChildren().remove(reactorNode);
reactorNode = new Group();
node.getChildren().add(reactorNode);
// Create the two straight sides
side1 = new Box(thickness, height, depth);
......@@ -192,8 +197,8 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
// coordinates, etc
float[] vertices = new float[blockSize * 2];
// At each sample point, create the four four vertices defining a
// rectagular slice of the semicircle
// At each sample point, create the four vertices defining a
// rectangular slice of the semicircle
for (int i = 0; i < samples; i++) {
// The bottom inner vertex
......@@ -316,36 +321,42 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
lowerArch.setTranslateY(-height / 2 - width / 2 - thickness / 2);
reactorNode.getChildren().add(lowerArch);
// If z is the highest dimension, rotate on the x axis
if (sizeY != height && sizeX != height && sizeZ == height) {
// Rotate the mesh such that its height is pointing in its longest
// direction and its hole is pointing along its shortest distance
// Rotate on the z axis if the X is the height or Z is the height and
// Y is the width
if ((sizeX > sizeY && sizeX > sizeZ)
|| (sizeZ > sizeY && sizeY > sizeX)) {
Rotate temp = new Rotate();
temp.setAxis(Rotate.X_AXIS);
temp.setAxis(Rotate.Z_AXIS);
temp.setAngle(90);
reactorNode.getTransforms().add(temp);
}
// If z is the widest dimension, rotate on the y axis
else if (sizeY != width && sizeX != width && sizeZ == width) {
// If z is the highest dimension, rotate on the x axis
if (sizeY != height && sizeX != height && sizeZ == height) {
Rotate temp = new Rotate();
temp.setAxis(Rotate.Y_AXIS);
temp.setAxis(Rotate.X_AXIS);
temp.setAngle(90);
reactorNode.getTransforms().add(temp);
}
// Rotate on the z axis if the X is the height or Z is the height and Y
// is the width
if ((sizeX > sizeY && sizeX > sizeZ)
|| (sizeZ > sizeY && sizeY > sizeX)) {
// If z is the widest dimension, rotate on the y axis
else if (sizeY != origWidth && sizeX != origWidth
&& sizeZ == origWidth) {
Rotate temp = new Rotate();
temp.setAxis(Rotate.Z_AXIS);
temp.setAxis(Rotate.Y_AXIS);
temp.setAngle(90);
reactorNode.getTransforms().add(temp);
}
// Move the reactor to surround the region
reactorNode.setTranslateX((bounds.getMinX() + bounds.getMaxX()) / 2);
reactorNode.setTranslateY((bounds.getMinY() + bounds.getMaxY()) / 2);
reactorNode.setTranslateZ((bounds.getMinZ() + bounds.getMaxZ()) / 2);
reactorNode.setTranslateX(
(bounds.getMaxX() - bounds.getMinX()) / 2 + bounds.getMinX());
reactorNode.setTranslateY(
(bounds.getMaxY() - bounds.getMinY()) / 2 + bounds.getMinY());
reactorNode.setTranslateZ(
(bounds.getMaxZ() - bounds.getMinZ()) / 2 + bounds.getMinZ());
}
......@@ -400,6 +411,20 @@ public class FXReactorView extends AbstractView implements IWireFramePart {
return node;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ice.viz.service.modeling.AbstractView#refresh(org.eclipse.ice
* .viz.service.modeling.AbstractMesh)
*/
@Override
public void refresh(AbstractMesh model) {
// Redraw the mesh
createShape((ReactorMesh) model);
}
/*
* (non-Javadoc)
*
......
......@@ -44,7 +44,7 @@ public class ShapeController extends AbstractController {
* @param parent
* The new shape which serves as this shape's parent.
*/
public void setParent(ShapeController parent) {
public void setParent(AbstractController parent) {
((ShapeMesh) model).setParent(parent);
}
......
......@@ -41,7 +41,7 @@ public class ShapeMesh extends AbstractMesh {
* @param parent
* The new shape which serves as this shape's parent.
*/
public void setParent(ShapeController parent) {
public void setParent(AbstractController parent) {
// Get the current list of parents
List<AbstractController> parentList = getEntitiesByCategory("Parent");
......@@ -128,8 +128,7 @@ public class ShapeMesh extends AbstractMesh {
// Set self as parent to any children
if (category == "Children") {
((ShapeController) newEntity)
.setParent(((ShapeController) controller));
((ShapeController) newEntity).setParent((controller));
}
super.addEntityByCategory(newEntity, category);
......@@ -138,7 +137,7 @@ public class ShapeMesh extends AbstractMesh {