use of com.ardor3d.bounding.OrientedBoundingBox in project energy3d by concord-consortium.
the class PrintController method computePageDimension.
private void computePageDimension() {
spaceBetweenParts = Scene.getInstance().areAnnotationsVisible() ? 3.0 : 0;
double fromPageToWorldCoord;
if (!isScaleToFit) {
fromPageToWorldCoord = exactFromPageToWorldCoord / (Scene.getInstance().getAnnotationScale() / 10.0);
} else {
double maxWidth = 0;
double maxHeight = 0;
for (final HousePart printPart : printParts) {
if (printPart.isPrintable()) {
if (printPart instanceof Roof) {
for (final Spatial roofPartNode : ((Roof) printPart).getRoofPartsRoot().getChildren()) {
if (roofPartNode.getSceneHints().getCullHint() != CullHint.Always) {
final OrientedBoundingBox boundingBox = (OrientedBoundingBox) ((Node) roofPartNode).getChild(0).getWorldBound().asType(Type.OBB);
final double width = Math.min(boundingBox.getExtent().getX(), boundingBox.getExtent().getZ());
final double height = Math.max(boundingBox.getExtent().getX(), boundingBox.getExtent().getZ());
if (width > maxWidth) {
maxWidth = width;
}
if (height > maxHeight) {
maxHeight = height;
}
}
}
} else {
final OrientedBoundingBox boundingBox = (OrientedBoundingBox) printPart.getMesh().getWorldBound().asType(Type.OBB);
final double width = Math.min(boundingBox.getExtent().getX(), boundingBox.getExtent().getZ());
final double height = Math.max(boundingBox.getExtent().getX(), boundingBox.getExtent().getZ());
if (width > maxWidth) {
maxWidth = width;
}
if (height > maxHeight) {
maxHeight = height;
}
}
}
}
maxWidth *= 2;
maxHeight *= 2;
maxWidth += 2 * spaceBetweenParts;
maxHeight += 2 * spaceBetweenParts;
final double ratio = pageFormat.getImageableWidth() / pageFormat.getImageableHeight();
if (maxWidth / maxHeight > ratio) {
pageWidth = ratio < 1 ? Math.min(maxWidth, maxHeight) : Math.max(maxWidth, maxHeight);
pageHeight = pageWidth / ratio;
} else {
pageHeight = ratio < 1 ? Math.max(maxWidth, maxHeight) : Math.min(maxWidth, maxHeight);
pageWidth = pageHeight * ratio;
}
fromPageToWorldCoord = pageWidth / pageFormat.getImageableWidth();
}
pageLeft = pageFormat.getImageableX() * fromPageToWorldCoord + spaceBetweenParts / 2.0;
pageRight = (pageFormat.getImageableX() + pageFormat.getImageableWidth()) * fromPageToWorldCoord - spaceBetweenParts / 2.0;
pageTop = pageFormat.getImageableY() * fromPageToWorldCoord + spaceBetweenParts / 2.0;
if (labelHeight == 0.0) {
final BMText label = Annotation.makeNewLabel(1);
label.setFontScale(0.5);
labelHeight = label.getHeight();
}
pageBottom = (pageFormat.getImageableY() + pageFormat.getImageableHeight()) * fromPageToWorldCoord;
pageWidth = pageFormat.getWidth() * fromPageToWorldCoord;
pageHeight = pageFormat.getHeight() * fromPageToWorldCoord;
}
use of com.ardor3d.bounding.OrientedBoundingBox in project energy3d by concord-consortium.
the class PrintController method fitInPage.
private boolean fitInPage(final Spatial printPart, final ArrayList<Spatial> page) {
for (final Spatial neighborPart : page) {
final Vector3 neighborPartCenter = ((UserData) neighborPart.getUserData()).getPrintCenter();
final OrientedBoundingBox neighborBound = (OrientedBoundingBox) neighborPart.getWorldBound().asType(Type.OBB);
final OrientedBoundingBox printPartBound = (OrientedBoundingBox) printPart.getWorldBound().asType(Type.OBB);
final double xExtend = neighborBound.getExtent().getX() + printPartBound.getExtent().getX() + spaceBetweenParts;
final double zExtend = neighborBound.getExtent().getZ() + printPartBound.getExtent().getZ() + spaceBetweenParts;
for (double angleQuarter = 0; angleQuarter < 4; angleQuarter++) {
final boolean isHorizontal = angleQuarter % 2 == 0;
final Vector3 tryCenter = new Matrix3().fromAngles(0, angleQuarter * Math.PI / 2.0, 0).applyPost(new Vector3(isHorizontal ? xExtend : zExtend, 0, 0), null);
tryCenter.addLocal(neighborPartCenter);
if (!isHorizontal) {
tryCenter.setX(pageLeft + printPartBound.getExtent().getX());
}
if (!isHorizontal) {
tryCenter.setX(MathUtils.clamp(tryCenter.getX(), pageLeft + printPartBound.getExtent().getX(), pageRight - printPartBound.getExtent().getX()));
} else {
tryCenter.setZ(MathUtils.clamp(tryCenter.getZ(), -pageBottom + printPartBound.getExtent().getZ(), -pageTop - printPartBound.getExtent().getZ()));
}
tryCenter.setY(Scene.getOriginalHouseRoot().getWorldBound().getCenter().getY());
boolean collision = false;
if (tryCenter.getX() - printPartBound.getExtent().getX() < pageLeft - MathUtils.ZERO_TOLERANCE || tryCenter.getX() + printPartBound.getExtent().getX() > pageRight + MathUtils.ZERO_TOLERANCE || tryCenter.getZ() + printPartBound.getExtent().getZ() > -pageTop + MathUtils.ZERO_TOLERANCE || tryCenter.getZ() - printPartBound.getExtent().getZ() < -pageBottom - MathUtils.ZERO_TOLERANCE) {
collision = true;
} else {
for (final Spatial otherPart : page) {
printPartBound.setCenter(tryCenter);
final OrientedBoundingBox otherPartBound = (OrientedBoundingBox) otherPart.getWorldBound().asType(Type.OBB);
otherPartBound.setCenter(((UserData) otherPart.getUserData()).getPrintCenter());
if (printPartBound.getExtent().getX() + otherPartBound.getExtent().getX() > Math.abs(printPartBound.getCenter().getX() - otherPartBound.getCenter().getX()) - spaceBetweenParts + MathUtils.ZERO_TOLERANCE && printPartBound.getExtent().getZ() + otherPartBound.getExtent().getZ() > Math.abs(printPartBound.getCenter().getZ() - otherPartBound.getCenter().getZ()) - spaceBetweenParts + MathUtils.ZERO_TOLERANCE) {
collision = true;
break;
}
}
}
if (!collision) {
((UserData) printPart.getUserData()).setPrintCenter(tryCenter);
page.add(printPart);
return true;
}
}
}
return false;
}
use of com.ardor3d.bounding.OrientedBoundingBox in project energy3d by concord-consortium.
the class Util method getOrientedBoundingBox.
public static OrientedBoundingBox getOrientedBoundingBox(final Node node) {
int count = 0;
for (final Spatial s : node.getChildren()) {
if (s instanceof Mesh) {
final Mesh m = (Mesh) s;
count += m.getMeshData().getVertexBuffer().limit();
}
}
final FloatBuffer newbuf = BufferUtils.createFloatBuffer(count);
for (final Spatial s : node.getChildren()) {
if (s instanceof Mesh) {
final Mesh m = (Mesh) s;
final FloatBuffer buf = m.getMeshData().getVertexBuffer();
buf.rewind();
while (buf.hasRemaining()) {
final Vector3 v = new Vector3(buf.get(), buf.get(), buf.get());
m.getWorldTransform().applyForward(v);
newbuf.put(v.getXf()).put(v.getYf()).put(v.getZf());
}
}
}
final OrientedBoundingBox boundingBox = new OrientedBoundingBox();
boundingBox.computeFromPoints(newbuf);
boundingBox.transform(node.getWorldTransform().invert(null), node.getWorldBound());
// node.updateWorldBound(true);
return boundingBox;
}
use of com.ardor3d.bounding.OrientedBoundingBox in project energy3d by concord-consortium.
the class Util method getOrientedBoundingBox.
public static OrientedBoundingBox getOrientedBoundingBox(final Mesh mesh) {
final FloatBuffer buf = mesh.getMeshData().getVertexBuffer();
buf.rewind();
final FloatBuffer newbuf = BufferUtils.createFloatBuffer(buf.limit());
while (buf.hasRemaining()) {
final Vector3 v = new Vector3(buf.get(), buf.get(), buf.get());
mesh.getWorldTransform().applyForward(v);
newbuf.put(v.getXf()).put(v.getYf()).put(v.getZf());
}
final OrientedBoundingBox boundingBox = new OrientedBoundingBox();
boundingBox.computeFromPoints(newbuf);
boundingBox.transform(mesh.getWorldTransform().invert(null), mesh.getModelBound());
mesh.updateWorldBound(true);
return boundingBox;
}
use of com.ardor3d.bounding.OrientedBoundingBox in project energy3d by concord-consortium.
the class EnergyPanel method updateProperties.
// As this method may be called from a non-Event-Queue thread, updating GUI must be done through invokeLater.
public void updateProperties() {
// update part properties
final HousePart selectedPart = SceneManager.getInstance().getSelectedPart();
final boolean energyViewShown = MainPanel.getInstance().getEnergyButton().isSelected();
final double meterToFoot;
final String lengthUnit;
switch(Scene.getInstance().getUnit()) {
case USCustomaryUnits:
meterToFoot = 3.28084;
lengthUnit = "ft";
break;
default:
meterToFoot = 1;
lengthUnit = "m";
}
final double scale = Scene.getInstance().getAnnotationScale() * meterToFoot;
final TitledBorder partPanelBorder = (TitledBorder) partPanel.getBorder();
if (selectedPart != null) {
final ReadOnlyVector3 v = selectedPart.getAbsPoint(0);
if (selectedPart instanceof Tree) {
final Tree tree = (Tree) selectedPart;
if (tree.isDrawable()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Tree (" + tree.getId() + "): " + tree.getTreeName());
partProperty1Label.setText(" Spread & Height:");
partProperty2Label.setText(" Type:");
partProperty3Label.setText(" Position:");
final double l = v.length();
double a = 90 + Math.toDegrees(Math.asin(-v.getY() / l));
if (v.getX() < 0) {
a = 360 - a;
}
if (Util.isZero(a - 360)) {
a = 0;
}
partProperty1TextField.setText(ONE_DECIMAL.format(tree.getWidth() * scale) + lengthUnit + ", " + ONE_DECIMAL.format(tree.getHeight() * scale) + lengthUnit);
partProperty2TextField.setText(tree.getTreeName() + " (" + (tree.getTreeType() == Tree.PINE ? "Evergreen" : "Deciduous") + ")");
partProperty3TextField.setText("(" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ")" + lengthUnit + " or (" + ONE_DECIMAL.format(l * scale) + lengthUnit + ", " + ONE_DECIMAL.format(a) + "\u00B0)");
partProperty1TextField.putClientProperty("tooltip", "The spread and height of the tree");
partProperty2TextField.putClientProperty("tooltip", "The type of the tree");
partProperty3TextField.putClientProperty("tooltip", "The (x, y) or polar coordinates on the land");
}
});
}
} else if (selectedPart instanceof Human) {
final Human human = (Human) selectedPart;
if (human.isDrawable()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Human (" + human.getId() + "): " + human.getHumanName());
partProperty1Label.setText(" X:");
partProperty2Label.setText(" Y:");
partProperty3Label.setText(" Z:");
partProperty1TextField.setText(ONE_DECIMAL.format(v.getX() * scale) + lengthUnit);
partProperty2TextField.setText(ONE_DECIMAL.format(v.getY() * scale) + lengthUnit);
partProperty3TextField.setText(ONE_DECIMAL.format(v.getZ() * scale) + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "X coordinate");
partProperty2TextField.putClientProperty("tooltip", "Y coordinate");
partProperty3TextField.putClientProperty("tooltip", "Z coordinate");
}
});
}
} else if (selectedPart instanceof SolarPanel) {
final SolarPanel sp = (SolarPanel) selectedPart;
if (sp.isDrawable()) {
final Foundation f = sp.getTopContainer();
if (f != null) {
double a = sp.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
final boolean flat = (sp.getContainer() instanceof Roof && Util.isZero(sp.getContainer().getHeight())) || (sp.getContainer() instanceof Foundation);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
String title = "Solar Panel (" + sp.getId() + "), " + (sp.getModelName() == null ? "" : "Model: " + sp.getModelName());
final String trackerName = sp.getTrackerName();
if (trackerName != null) {
title += ", Tracker: " + trackerName;
}
partPanelBorder.setTitle(title);
partProperty1Label.setText(" Size & Position:");
partProperty1TextField.setText(TWO_DECIMALS.format(sp.getPanelWidth() * meterToFoot) + "\u00d7" + TWO_DECIMALS.format(sp.getPanelHeight() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The length, width, and center coordinates of the solar panel");
partProperty2Label.setText(" Angles:");
partProperty2TextField.setText(flat ? "tilt: " + ONE_DECIMAL.format(Util.isZero(sp.getTiltAngle()) ? Math.toDegrees(Math.asin(sp.getNormal().getY())) : sp.getTiltAngle()) + "\u00B0, azimuth: " + ONE_DECIMAL.format(az) + "\u00B0" : " --- ");
partProperty2TextField.putClientProperty("tooltip", "The angles of the solar panel");
final String eff = ONE_DECIMAL.format(sp.getCellEfficiency() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Efficiency & Yield:");
partProperty3TextField.setText(eff + ", " + TWO_DECIMALS.format(sp.getSolarPotentialToday()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The solar cell efficiency and daily yield of the solar panel");
} else {
partProperty3Label.setText(" Efficiency:");
partProperty3TextField.setText(eff);
partProperty3TextField.putClientProperty("tooltip", "The solar cell efficiency of the solar panel");
}
}
});
}
}
} else if (selectedPart instanceof Rack) {
final Rack rack = (Rack) selectedPart;
if (rack.isDrawable()) {
final Foundation f = rack.getTopContainer();
if (f != null) {
double a = rack.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
final int n = rack.isMonolithic() ? rack.getNumberOfSolarPanels() : rack.getChildren().size();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
String title = "Rack (" + rack.getId() + ")";
final SolarPanel s = rack.getSolarPanel();
if (s.getModelName() != null) {
title += ", Model: " + s.getModelName();
}
final String trackerName = rack.getTrackerName();
if (trackerName != null) {
title += ", Tracker: " + trackerName;
}
partPanelBorder.setTitle(title);
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(rack.getRackWidth() * meterToFoot) + "\u00d7" + TWO_DECIMALS.format(rack.getRackHeight() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The length, width, and center coordinates of the rack");
partProperty2Label.setText(" Angles:");
partProperty2TextField.setText("tilt: " + ONE_DECIMAL.format(Util.isZero(rack.getTiltAngle()) ? Math.toDegrees(Math.asin(rack.getNormal().getY())) : rack.getTiltAngle()) + "\u00B0, azimuth: " + ONE_DECIMAL.format(az) + "\u00B0");
partProperty2TextField.putClientProperty("tooltip", "The angles of the rack");
partProperty3Label.setText(" Solar Panels:");
final SolarPanel sp = rack.getSolarPanel();
final String eff = ONE_DECIMAL.format(sp.getCellEfficiency() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Efficiency & Yield:");
partProperty3TextField.setText(eff + ", " + TWO_DECIMALS.format(rack.getSolarPotentialToday()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The solar cell efficiency and daily yield of the solar panel array on the rack");
} else {
if (rack.isMonolithic()) {
final int[] rnc = rack.getSolarPanelRowAndColumnNumbers();
partProperty3TextField.setText("" + n + " (" + rnc[0] + "\u00D7" + rnc[1] + "), " + s.getPanelWidth() + "\u00D7" + s.getPanelHeight() + lengthUnit + ", " + eff);
} else {
partProperty3TextField.setText("" + n);
}
partProperty3TextField.putClientProperty("tooltip", "Number and type of solar panels on this rack");
}
}
});
}
}
} else if (selectedPart instanceof Mirror) {
final Mirror m = (Mirror) selectedPart;
if (m.isDrawable()) {
final Foundation f = m.getTopContainer();
if (f != null) {
double a = m.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
final boolean flat = m.getContainer() instanceof Foundation;
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Heliostat (" + m.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(m.getMirrorWidth() * meterToFoot) + "\u00d7" + TWO_DECIMALS.format(m.getMirrorHeight() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The length, width, and center coordinates of the heliostat");
partProperty2Label.setText(" Angles:");
partProperty2TextField.setText(flat ? "tilt: " + ONE_DECIMAL.format(m.getTiltAngle()) + "\u00B0, azimuth: " + ONE_DECIMAL.format(az) + "\u00B0" : " --- ");
partProperty2TextField.putClientProperty("tooltip", "The angles of the heliostat");
final Foundation receiver = m.getReceiver();
final String s = "R=" + ONE_DECIMAL.format(m.getReflectance() * 100) + "%" + (receiver == null ? "" : ", \u03B7=" + ONE_DECIMAL.format(receiver.getSolarReceiverEfficiency() * 100) + "%");
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(s + ", " + ONE_DECIMAL.format(m.getSolarPotentialToday() * m.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The physical properties and electric yield of this heliostat");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(s);
partProperty3TextField.putClientProperty("tooltip", "The physical properties of this heliostat");
}
}
});
}
}
} else if (selectedPart instanceof ParabolicTrough) {
final ParabolicTrough t = (ParabolicTrough) selectedPart;
if (t.isDrawable()) {
final Foundation f = t.getTopContainer();
if (f != null) {
double a = t.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
// http://www.powerfromthesun.net/Book/chapter08/chapter08.html
final double focalLength = t.getSemilatusRectum() * 0.5;
final double d = t.getApertureWidth();
final double h = d * d / (16 * focalLength);
final double rimAngle = Math.toDegrees(Math.atan(1.0 / (d / (8 * h) - (2 * h) / d)));
final double b = 4 * h / d;
final double c = Math.sqrt(b * b + 1);
final double s = 0.5 * d * c + 2 * focalLength * Math.log(b + c);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Parabolic Trough (" + t.getId() + ")");
partProperty1Label.setText(" Length & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(t.getTroughLength() * meterToFoot) + lengthUnit + ", module:" + TWO_DECIMALS.format(t.getModuleLength() * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit + ", azimuth:" + ONE_DECIMAL.format(az) + "\u00B0");
partProperty1TextField.putClientProperty("tooltip", "Assembly length, module length, center coordinates, and azimith of the parabolic trough");
partProperty2Label.setText(" Parabola Shape:");
partProperty2TextField.setText("f=" + ONE_DECIMAL.format(focalLength * meterToFoot) + lengthUnit + ", d=" + ONE_DECIMAL.format(t.getApertureWidth() * meterToFoot) + lengthUnit + ", h=" + ONE_DECIMAL.format(h * meterToFoot) + lengthUnit + ", \u03C6=" + ONE_DECIMAL.format(rimAngle >= 0 ? rimAngle : 180 + rimAngle) + "\u00B0");
partProperty2TextField.putClientProperty("tooltip", "Parameters of the parabolic shape");
final String str = "R=" + ONE_DECIMAL.format(t.getReflectance() * 100) + "%, s=" + ONE_DECIMAL.format(s * t.getTroughLength() * meterToFoot * meterToFoot) + lengthUnit + "\u00B2, a=" + ONE_DECIMAL.format(d * t.getTroughLength() * meterToFoot * meterToFoot) + lengthUnit + "\u00B2, \u03B1=" + ONE_DECIMAL.format(t.getAbsorptance() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(str + ", " + ONE_DECIMAL.format(t.getSolarPotentialToday() * t.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The properties and yield of this parabolic trough");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(str);
partProperty3TextField.putClientProperty("tooltip", "The properties of this parabolic trough");
}
}
});
}
}
} else if (selectedPart instanceof ParabolicDish) {
final ParabolicDish d = (ParabolicDish) selectedPart;
if (d.isDrawable()) {
final Foundation f = d.getTopContainer();
if (f != null) {
double a = d.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double focalLength = d.getFocalLength();
final double rimRadius = d.getRimRadius();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Parabolic Dish (" + d.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText("Rim radius=" + TWO_DECIMALS.format(rimRadius * meterToFoot) + lengthUnit + ", (" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "Rim radius and center coordinates of the parabolic dish");
partProperty2Label.setText(" Parabola Shape:");
partProperty2TextField.setText("Focal length=" + ONE_DECIMAL.format(focalLength * meterToFoot) + lengthUnit);
partProperty2TextField.putClientProperty("tooltip", "Parameters of the parabolic shape");
final String str = "R=" + ONE_DECIMAL.format(d.getReflectance() * 100) + "%, \u03B1=" + ONE_DECIMAL.format(d.getAbsorptance() * 100) + "%";
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(str + ", " + ONE_DECIMAL.format(d.getSolarPotentialToday() * d.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The properties and yield of this parabolic dish");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(str);
partProperty3TextField.putClientProperty("tooltip", "The properties of this parabolic dish");
}
}
});
}
}
} else if (selectedPart instanceof FresnelReflector) {
final FresnelReflector r = (FresnelReflector) selectedPart;
if (r.isDrawable()) {
final Foundation f = r.getTopContainer();
if (f != null) {
double a = r.getRelativeAzimuth() + f.getAzimuth();
if (a >= 360) {
a -= 360;
}
final double az = a;
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Fresnel Reflector (" + r.getId() + ")");
partProperty1Label.setText(" Center & Azimuth:");
partProperty1TextField.setText("(" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit + ", azimuth:" + ONE_DECIMAL.format(az) + "\u00B0");
partProperty1TextField.putClientProperty("tooltip", "Center coordinates and azimuth of the Fresnel reflector");
partProperty2Label.setText(" Length & Width:");
partProperty2TextField.setText(TWO_DECIMALS.format(r.getLength() * meterToFoot) + lengthUnit + ", module:" + TWO_DECIMALS.format(r.getModuleLength() * meterToFoot) + lengthUnit + ", " + ONE_DECIMAL.format(r.getModuleWidth() * meterToFoot) + lengthUnit);
partProperty2TextField.putClientProperty("tooltip", "Assembly length, module length, and width of the Fresnel reflector");
final Foundation receiver = r.getReceiver();
final String str = "R=" + ONE_DECIMAL.format(r.getReflectance() * 100) + "%, a=" + ONE_DECIMAL.format(r.getModuleWidth() * r.getLength() * meterToFoot * meterToFoot) + lengthUnit + "\u00B2" + (receiver == null ? "" : ", \u03B7=" + ONE_DECIMAL.format(receiver.getSolarReceiverEfficiency() * 100) + "%");
if (energyViewShown) {
partProperty3Label.setText(" Properties & Yield:");
partProperty3TextField.setText(str + ", " + ONE_DECIMAL.format(r.getSolarPotentialToday() * r.getSystemEfficiency()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The properties and yield of this Fresnel reflector");
} else {
partProperty3Label.setText(" Properties:");
partProperty3TextField.setText(str);
partProperty3TextField.putClientProperty("tooltip", "The properties of this Fresnel reflector");
}
}
});
}
}
} else if (selectedPart instanceof Sensor) {
final Sensor sensor = (Sensor) selectedPart;
if (sensor.isDrawable()) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Sensor (" + sensor.getId() + ")");
partProperty1Label.setText(" Position:");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Light:");
partProperty1TextField.setText("(" + ONE_DECIMAL.format(v.getX() * scale) + ", " + ONE_DECIMAL.format(v.getY() * scale) + ", " + ONE_DECIMAL.format(v.getZ() * scale) + ")" + lengthUnit);
partProperty2TextField.setText(TWO_DECIMALS.format(-sensor.getTotalHeatLoss() / sensor.getArea()) + " kWh/day/m\u00B2");
partProperty3TextField.setText(TWO_DECIMALS.format(sensor.getSolarPotentialToday() / sensor.getArea()) + " kWh/day/m\u00B2");
partProperty1TextField.putClientProperty("tooltip", "The (x, y, z) coordinates of the sensor");
partProperty2TextField.putClientProperty("tooltip", "The heat flux measured by the sensor");
partProperty3TextField.putClientProperty("tooltip", "The light intensity measured by the sensor");
}
});
}
} else if (selectedPart instanceof Foundation) {
final Foundation foundation = (Foundation) selectedPart;
if (foundation.isDrawable()) {
final Vector3 v1 = foundation.getAbsPoint(1);
final Vector3 v2 = foundation.getAbsPoint(2);
final Vector3 v3 = foundation.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double lx = v.distance(v2);
final double ly = v.distance(v1);
final double lz = foundation.getHeight();
final double az = foundation.getAzimuth();
final String landArea;
final FoundationPolygon polygon = foundation.getPolygon();
if (polygon != null && polygon.isVisible()) {
landArea = " (inset:" + ONE_DECIMAL.format(polygon.getArea()) + ")";
} else {
landArea = "";
}
final Mesh selectedMesh;
final Node selectedNode;
final OrientedBoundingBox nodeBox, meshBox;
final List<Node> nodes = foundation.getImportedNodes();
if (nodes != null) {
selectedMesh = foundation.getSelectedMesh();
if (selectedMesh != null) {
selectedNode = selectedMesh.getParent();
nodeBox = Util.getOrientedBoundingBox(selectedNode);
meshBox = Util.getOrientedBoundingBox(selectedMesh);
} else {
selectedNode = null;
nodeBox = null;
meshBox = null;
}
} else {
selectedMesh = null;
selectedNode = null;
nodeBox = null;
meshBox = null;
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (selectedNode != null) {
final double xNodeBox = 2 * nodeBox.getExtent().getX() * scale;
final double yNodeBox = 2 * nodeBox.getExtent().getY() * scale;
final double zNodeBox = 2 * nodeBox.getExtent().getZ() * scale;
final double xMeshBox = 2 * meshBox.getExtent().getX() * scale;
final double yMeshBox = 2 * meshBox.getExtent().getY() * scale;
final double zMeshBox = 2 * meshBox.getExtent().getZ() * scale;
final ReadOnlyVector3 meshBoxCenter = meshBox.getCenter();
final NodeState ns = foundation.getNodeState(selectedNode);
final Vector3 position = ns.getRelativePosition().add(foundation.getAbsCenter(), null);
Vector3 meshNormal = null;
int meshIndex = -1;
if (selectedMesh.getUserData() instanceof UserData) {
final UserData ud = (UserData) selectedMesh.getUserData();
meshIndex = ud.getMeshIndex();
meshNormal = (Vector3) ud.getNormal();
if (!Util.isZero(az)) {
selectedNode.getRotation().applyPost(meshNormal, meshNormal);
}
}
// System.out.println(">>>" + Util.computeFirstNormal(selectedMesh) + ", " + Util.getFirstNormalFromBuffer(selectedMesh));
final String meshBoxString = TWO_DECIMALS.format(xMeshBox) + "\u00d7" + (TWO_DECIMALS.format(yMeshBox)) + "\u00d7" + (TWO_DECIMALS.format(zMeshBox)) + lengthUnit;
final String meshCenterString = "(" + ONE_DECIMAL.format(meshBoxCenter.getX() * scale) + ", " + ONE_DECIMAL.format(meshBoxCenter.getY() * scale) + ", " + ONE_DECIMAL.format(meshBoxCenter.getZ() * scale) + ")" + lengthUnit;
final String meshNormalString = meshNormal != null ? "(" + TWO_DECIMALS.format(meshNormal.getX()) + ", " + TWO_DECIMALS.format(meshNormal.getY()) + ", " + TWO_DECIMALS.format(meshNormal.getZ()) + ")" : "";
partPanelBorder.setTitle("Node #" + foundation.getImportedNodes().indexOf(selectedNode) + " (" + Util.getFileName(ns.getSourceURL().getPath()).replace("%20", " ") + "), Mesh #" + meshIndex + ", Base #" + foundation.getId());
partProperty1Label.setText(" Node:");
partProperty2Label.setText(" Mesh:");
partProperty1TextField.setText(TWO_DECIMALS.format(xNodeBox) + "\u00d7" + (TWO_DECIMALS.format(yNodeBox)) + "\u00d7" + (TWO_DECIMALS.format(zNodeBox)) + lengthUnit + ", (" + TWO_DECIMALS.format(position.getX() * scale) + ", " + TWO_DECIMALS.format(position.getY() * scale) + ")" + lengthUnit);
partProperty2TextField.setText(meshBoxString + ", " + meshCenterString);
partProperty1TextField.putClientProperty("tooltip", "Dimension and location of the bounding box of the selected node<br>File:" + ns.getSourceURL().getFile());
partProperty2TextField.putClientProperty("tooltip", "Dimension and location of the bounding box of the selected mesh");
if (energyViewShown) {
double dailyMeshSolarPotential = 0;
final double[] meshSolarPotential = SolarRadiation.getInstance().getSolarPotential(selectedMesh);
for (final double x : meshSolarPotential) {
dailyMeshSolarPotential += x;
}
partProperty3Label.setText(" Solar:");
partProperty3TextField.setText("\u2191" + meshNormalString + ", " + TWO_DECIMALS.format(dailyMeshSolarPotential) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "Normal vector and solar potential of the selected mesh");
} else {
partProperty3Label.setText(" Normal:");
partProperty3TextField.setText("\u2191" + meshNormalString + ", " + selectedMesh.getMeshData().getVertexCount() + " vertices");
partProperty3TextField.putClientProperty("tooltip", "Normal vector and vertex count of the selected mesh");
}
} else {
partPanelBorder.setTitle("Foundation (" + foundation.getId() + ")");
partProperty1Label.setText(" Size:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx * scale) + "\u00d7" + (TWO_DECIMALS.format(ly * scale)) + "\u00d7" + (TWO_DECIMALS.format(lz * scale)) + lengthUnit + ", Area\u2248" + ONE_DECIMAL.format(lx * ly * scale * scale) + landArea + lengthUnit + "\u00B2");
partProperty1TextField.putClientProperty("tooltip", "The length and width of the foundation");
partProperty2Label.setText(" Position:");
partProperty2TextField.setText("(" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ")" + lengthUnit);
partProperty2TextField.putClientProperty("tooltip", "The (x, y) coordinate of the center of the foundation");
partProperty3Label.setText(" Azimuth:");
partProperty3TextField.setText(TWO_DECIMALS.format(az) + "\u00B0");
partProperty3TextField.putClientProperty("tooltip", "The azimuth of the reference edge");
}
}
});
}
} else if (selectedPart instanceof Roof) {
final Roof roof = (Roof) selectedPart;
if (roof.isDrawable()) {
final double area = roof.getArea();
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Roof (" + roof.getId() + ")");
partProperty1Label.setText(" Area & Rise:");
partProperty1TextField.setText("Area = " + TWO_DECIMALS.format(area) + lengthUnit + "\u00B2, Rise = " + TWO_DECIMALS.format(roof.getHeight() * scale) + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The total area and the rise of the roof<br>(The rise is the highest point of the roof to the top of the walls.)");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String rval = ONE_DECIMAL.format(Util.toUsRValue(roof.getUValue()));
final boolean isBuildingProject = Scene.getInstance().getProjectType() == Foundation.TYPE_BUILDING;
final float absorptance = 1 - roof.getAlbedo();
if (energyViewShown) {
partProperty2TextField.setText("R-value = " + rval + ", Gain = " + TWO_DECIMALS.format(-roof.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The R-value and daily thermal gain of the roof");
if (isBuildingProject) {
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance) + ", Absorption = " + TWO_DECIMALS.format(roof.getSolarPotentialToday() * absorptance) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The absorptance and daily solar heat gain of the roof surface");
} else {
partProperty3TextField.setText("Radiation energy = " + TWO_DECIMALS.format(roof.getSolarPotentialToday()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The solar radiation energy onto this roof surface");
}
} else {
partProperty2TextField.setText("R-value = " + rval + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The R-value of the roof");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance));
partProperty3TextField.putClientProperty("tooltip", "The absorptance of the roof surface");
}
}
});
}
} else if (selectedPart instanceof Window) {
final Window window = (Window) selectedPart;
if (window.isDrawable()) {
final double lx = window.getWindowWidth();
final double ly = window.getWindowHeight();
final Vector3 v1 = window.getAbsPoint(1);
final Vector3 v2 = window.getAbsPoint(2);
final Vector3 v3 = window.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double cz = 0.25 * (v.getZ() + v1.getZ() + v2.getZ() + v3.getZ());
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Window (" + window.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx) + "\u00d7" + (TWO_DECIMALS.format(ly)) + lengthUnit + " \u2248 " + TWO_DECIMALS.format(lx * ly) + lengthUnit + "\u00B2, (" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ", " + TWO_DECIMALS.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The width, height, and center of the window");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String shgc = TWO_DECIMALS.format(window.getSolarHeatGainCoefficient());
if (energyViewShown) {
partProperty2TextField.setText("U-Value = " + TWO_DECIMALS.format(Util.toUsUValue(window.getUValue())) + ", Gain = " + TWO_DECIMALS.format(-window.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The U-value and daily thermal gain of the window");
partProperty3TextField.setText("SHGC = " + shgc + ", Gain = " + TWO_DECIMALS.format(window.getSolarPotentialToday() * window.getSolarHeatGainCoefficient()) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The SHGC value and daily solar gain of the window");
} else {
partProperty2TextField.setText("U-Value = " + TWO_DECIMALS.format(Util.toUsUValue(window.getUValue())) + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The U-value of the window");
partProperty3TextField.setText("SHGC = " + shgc);
partProperty3TextField.putClientProperty("tooltip", "The solar heat gain coefficient (SHGC) of the window");
}
}
});
}
} else if (selectedPart instanceof Wall) {
final Wall wall = (Wall) selectedPart;
if (wall.isDrawable()) {
final Vector3 v1 = wall.getAbsPoint(1);
final Vector3 v2 = wall.getAbsPoint(2);
final Vector3 v3 = wall.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double cz = 0.25 * (v.getZ() + v1.getZ() + v2.getZ() + v3.getZ());
final double lx = v.distance(v2);
final double ly = v.distance(v1);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Wall (" + wall.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx * scale) + "\u00d7" + (TWO_DECIMALS.format(ly * scale)) + lengthUnit + " \u2248 " + TWO_DECIMALS.format(lx * ly * scale * scale) + lengthUnit + " \u00B2, " + "(" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ", " + TWO_DECIMALS.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The width, height, and center of the wall");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String rval = ONE_DECIMAL.format(Util.toUsRValue(wall.getUValue()));
final float absorptance = 1 - wall.getAlbedo();
if (energyViewShown) {
partProperty2TextField.setText("R-Value = " + rval + ", Gain = " + TWO_DECIMALS.format(-wall.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The R-value and daily thermal gain of the wall");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance) + ", Absorption = " + TWO_DECIMALS.format(wall.getSolarPotentialToday() * absorptance) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The absorptance and daily solar heat gain of the wall surface");
} else {
partProperty2TextField.setText("R-Value = " + rval + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The R-value of the wall");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance));
partProperty3TextField.putClientProperty("tooltip", "The absorptance of the wall surface");
}
}
});
}
} else if (selectedPart instanceof Door) {
final Door door = (Door) selectedPart;
if (door.isDrawable()) {
final Vector3 v1 = door.getAbsPoint(1);
final Vector3 v2 = door.getAbsPoint(2);
final Vector3 v3 = door.getAbsPoint(3);
final double cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
final double cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
final double cz = 0.25 * (v.getZ() + v1.getZ() + v2.getZ() + v3.getZ());
final double lx = v.distance(v2);
final double ly = v.distance(v1);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Door (" + door.getId() + ")");
partProperty1Label.setText(" Size & Center:");
partProperty1TextField.setText(TWO_DECIMALS.format(lx * scale) + "\u00d7" + (TWO_DECIMALS.format(ly * scale)) + lengthUnit + " \u2248 " + TWO_DECIMALS.format(lx * ly * scale * scale) + lengthUnit + "\u00B2, (" + TWO_DECIMALS.format(cx * scale) + ", " + TWO_DECIMALS.format(cy * scale) + ", " + TWO_DECIMALS.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The width, height, and center of the door");
partProperty2Label.setText(" Thermal:");
partProperty3Label.setText(" Solar:");
final String uval = TWO_DECIMALS.format(Util.toUsUValue(door.getUValue()));
final float absorptance = 1 - door.getAlbedo();
if (energyViewShown) {
partProperty2TextField.setText("U-Value = " + uval + ", Gain = " + TWO_DECIMALS.format(-door.getTotalHeatLoss()) + " kWh");
partProperty2TextField.putClientProperty("tooltip", "The R-value and daily thermal gain of the door");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance) + ", Absorption = " + TWO_DECIMALS.format(door.getSolarPotentialToday() * absorptance) + " kWh");
partProperty3TextField.putClientProperty("tooltip", "The absorptance and daily solar heat gain of the door surface");
} else {
partProperty2TextField.setText("U-Value = " + uval + " (US system)");
partProperty2TextField.putClientProperty("tooltip", "The U-value of the door");
partProperty3TextField.setText("Absorptance = " + TWO_DECIMALS.format(absorptance));
partProperty3TextField.putClientProperty("tooltip", "The absorptance of the door surface");
}
}
});
}
} else if (selectedPart instanceof Floor) {
final Floor floor = (Floor) selectedPart;
if (floor.isDrawable()) {
final double cx, cy;
final double cz = v.getZ();
if (floor.getPoints().size() > 1) {
final Vector3 v1 = floor.getAbsPoint(1);
final Vector3 v2 = floor.getAbsPoint(2);
final Vector3 v3 = floor.getAbsPoint(3);
cx = 0.25 * (v.getX() + v1.getX() + v2.getX() + v3.getX());
cy = 0.25 * (v.getY() + v1.getY() + v2.getY() + v3.getY());
} else {
cx = v.getX();
cy = v.getY();
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
partPanelBorder.setTitle("Floor (" + floor.getId() + ")");
partProperty1Label.setText(" Area & Center");
partProperty1TextField.setText(ONE_DECIMAL.format(floor.getArea()) + lengthUnit + "\u00B2, (" + ONE_DECIMAL.format(cx * scale) + ", " + ONE_DECIMAL.format(cy * scale) + ", " + ONE_DECIMAL.format(cz * scale) + ")" + lengthUnit);
partProperty1TextField.putClientProperty("tooltip", "The area and center of the floor");
partProperty2Label.setText(" Thermal:");
partProperty2TextField.setText("N.A.");
partProperty2TextField.putClientProperty("tooltip", "Not applicable to thermal analysis");
partProperty3Label.setText(" Solar:");
partProperty3TextField.setText("N.A.");
partProperty3TextField.putClientProperty("tooltip", "Not applicable to solar analysis");
}
});
}
}
} else {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final int numberOfSolarPanels = Scene.getInstance().countSolarPanels();
if (numberOfSolarPanels > 0) {
partPanelBorder.setTitle("Solar Panels");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfSolarPanels);
partProperty1TextField.putClientProperty("tooltip", "Total number of solar panels");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(PvProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of solar panels");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfHeliostats = Scene.getInstance().countParts(Mirror.class);
if (numberOfHeliostats > 0) {
partPanelBorder.setTitle("Heliostats");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfHeliostats);
partProperty1TextField.putClientProperty("tooltip", "Total number of heliostats");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of heliostats");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfParabolicTroughs = Scene.getInstance().countParts(ParabolicTrough.class);
if (numberOfParabolicTroughs > 0) {
partPanelBorder.setTitle("Parabolic Troughs");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfParabolicTroughs);
partProperty1TextField.putClientProperty("tooltip", "Total number of parabolic troughs");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of parabolic troughs");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfParabolicDishes = Scene.getInstance().countParts(ParabolicDish.class);
if (numberOfParabolicDishes > 0) {
partPanelBorder.setTitle("Parabolic Dishes");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfParabolicDishes);
partProperty1TextField.putClientProperty("tooltip", "Total number of parabolic dishes");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of parabolic dishes");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfFresnelReflectors = Scene.getInstance().countParts(FresnelReflector.class);
if (numberOfFresnelReflectors > 0) {
partPanelBorder.setTitle("Fresnel Reflectors");
partProperty1Label.setText(" Total Number:");
partProperty1TextField.setText("" + numberOfFresnelReflectors);
partProperty1TextField.putClientProperty("tooltip", "Total number of Fresnel reflectors");
partProperty2Label.setText(" Total Cost:");
partProperty2TextField.setText("$" + TWO_DECIMALS.format(CspProjectCost.getInstance().getTotalCost()));
partProperty2TextField.putClientProperty("tooltip", "Total cost of Fresnel reflectors");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
final int numberOfNodes = Scene.getInstance().countNodes();
if (numberOfNodes > 0) {
partPanelBorder.setTitle("Structures");
partProperty1Label.setText(" Total Nodes:");
partProperty1TextField.setText("" + numberOfNodes);
partProperty1TextField.putClientProperty("tooltip", "Total number of structure nodes");
partProperty2Label.setText(" Total Meshes:");
partProperty2TextField.setText("" + Scene.getInstance().countMeshes());
partProperty2TextField.putClientProperty("tooltip", "Total number of structure meshes");
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
} else {
partPanelBorder.setTitle(" -");
partProperty1Label.setText(" -");
partProperty1TextField.setText("");
partProperty1TextField.putClientProperty("tooltip", null);
partProperty2Label.setText(" -");
partProperty2TextField.setText("");
partProperty2TextField.putClientProperty("tooltip", null);
partProperty3Label.setText(" -");
partProperty3TextField.setText("");
partProperty3TextField.putClientProperty("tooltip", null);
}
}
}
}
}
}
}
});
}
partPanel.repaint();
// update building properties
final Foundation selectedFoundation;
if (selectedPart == null) {
selectedFoundation = null;
} else if (selectedPart instanceof Foundation) {
selectedFoundation = (Foundation) selectedPart;
} else {
selectedFoundation = selectedPart.getTopContainer();
}
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
if (selectedFoundation != null) {
switch(selectedFoundation.getProjectType()) {
case Foundation.TYPE_BUILDING:
dataPanel.remove(instructionPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.remove(cspProjectPanel);
dataPanel.add(buildingPanel, 2);
final Calendar c = Heliodon.getInstance().getCalendar();
final int temp = selectedFoundation.getThermostat().getTemperature(c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY, c.get(Calendar.HOUR_OF_DAY));
switch(Scene.getInstance().getUnit()) {
case InternationalSystemOfUnits:
thermostatTemperatureField.setText(temp + " \u00B0C");
break;
case USCustomaryUnits:
thermostatTemperatureField.setText(Math.round(32.0 + 9.0 * temp / 5.0) + " \u00B0F");
break;
}
thermostatPanel.add(adjustThermostatButton, BorderLayout.EAST);
String s2 = selectedFoundation.toString();
s2 = s2.substring(0, s2.indexOf(')') + 1);
final int i1 = s2.indexOf('(');
final int i2 = s2.indexOf(')');
((TitledBorder) buildingPanel.getBorder()).setTitle("Building #" + s2.substring(i1 + 1, i2));
buildingInfoPanel.update(selectedFoundation);
break;
case Foundation.TYPE_PV_PROJECT:
dataPanel.remove(instructionPanel);
dataPanel.remove(buildingPanel);
dataPanel.remove(cspProjectPanel);
dataPanel.add(pvProjectPanel, 2);
pvProjectInfoPanel.update(selectedFoundation);
break;
case Foundation.TYPE_CSP_PROJECT:
dataPanel.remove(instructionPanel);
dataPanel.remove(buildingPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.add(cspProjectPanel, 2);
cspProjectInfoPanel.update(selectedFoundation);
break;
case -1:
dataPanel.remove(instructionPanel);
dataPanel.remove(buildingPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.remove(cspProjectPanel);
break;
}
} else {
dataPanel.remove(buildingPanel);
dataPanel.remove(pvProjectPanel);
dataPanel.remove(cspProjectPanel);
dataPanel.add(instructionPanel, 2);
for (int i = 0; i < instructionSheets.length; i++) {
final String contentType = Scene.getInstance().getInstructionSheetTextType(i);
instructionSheets[i].setContentType(contentType == null ? "text/plain" : contentType);
if (!instructionSheets[i].getText().equals(Scene.getInstance().getInstructionSheetText(i))) {
instructionSheets[i].setText(Scene.getInstance().getInstructionSheetText(i));
}
}
}
dataPanel.validate();
dataPanel.repaint();
}
});
}
Aggregations