//
// NodeRendererJ3D.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.cluster;
import visad.*;
import visad.java3d.*;
import visad.util.Delay;
import java.awt.event.*;
import javax.swing.*;
import java.rmi.*;
/**
NodeRendererJ3D is the VisAD class for transforming
data into VisADSceneGraphObjects, but not rendering,
on cluster nodes
*/
public class NodeRendererJ3D extends DefaultRendererJ3D {
private NodeAgent agent = null;
private boolean enable_transform = false;
private int resolution = 1;
/** this constructor is need for NodeDisplayRendererJ3D.makeDefaultRenderer()
but it should never be called */
public NodeRendererJ3D () {
this(null);
}
/** this DataRenderer transforms data into VisADSceneGraphObjects,
but does not render, on cluster nodes;
send scene graphs back via NodeAgent */
public NodeRendererJ3D (NodeAgent a) {
super();
agent = a;
}
public ShadowType makeShadowFunctionType(
FunctionType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowNodeFunctionTypeJ3D(type, link, parent);
}
public ShadowType makeShadowRealTupleType(
RealTupleType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowNodeRealTupleTypeJ3D(type, link, parent);
}
public ShadowType makeShadowRealType(
RealType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowNodeRealTypeJ3D(type, link, parent);
}
public ShadowType makeShadowSetType(
SetType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowNodeSetTypeJ3D(type, link, parent);
}
public ShadowType makeShadowTupleType(
TupleType type, DataDisplayLink link, ShadowType parent)
throws VisADException, RemoteException {
return new ShadowNodeTupleTypeJ3D(type, link, parent);
}
public void setResolution(int r) {
resolution = r;
}
public int getResolution() {
return resolution;
}
public void enableTransform() {
enable_transform = true;
}
public DataShadow prepareAction(boolean go, boolean initialize,
DataShadow shadow)
throws VisADException, RemoteException {
// don't autoscale: initialize = false
return super.prepareAction(go, false, shadow);
}
/** re-transform if needed;
return false if not done */
public boolean doAction() throws VisADException, RemoteException {
boolean all_feasible = get_all_feasible();
boolean any_changed = get_any_changed();
boolean any_transform_control = get_any_transform_control();
if (all_feasible && (any_changed || any_transform_control)) {
/*
System.out.println("RendererJ3D.doAction: any_changed = " + any_changed +
" any_transform_control = " + any_transform_control);
System.out.println(getLinks()[0].getThingReference().getName());
*/
boolean branch = false;
// exceptionVector.removeAllElements();
clearAVControls();
try {
// doTransform creates a BranchGroup from a Data object
branch = fakeTransform();
}
catch (OutOfMemoryError e) {
// System.out.println("OutOfMemoryError, try again ...");
branch = false;
new Delay(250);
Runtime.getRuntime().gc();
Runtime.getRuntime().runFinalization();
try {
branch = fakeTransform();
}
catch (BadMappingException ee) {
addException(ee);
}
catch (UnimplementedException ee) {
addException(ee);
branch = false;
}
catch (RemoteException ee) {
addException(ee);
branch = false;
}
catch (DisplayInterruptException ee) {
branch = false;
}
}
catch (BadMappingException e) {
addException(e);
branch = false;
}
catch (UnimplementedException e) {
addException(e);
branch = false;
}
catch (RemoteException e) {
addException(e);
branch = false;
}
catch (DisplayInterruptException e) {
branch = false;
}
if (!branch) {
all_feasible = false;
set_all_feasible(all_feasible);
}
}
else { // !(all_feasible && (any_changed || any_transform_control))
DataDisplayLink[] links = getLinks();
for (int i=0; i<links.length; i++) {
links[i].clearData();
}
}
return (all_feasible && (any_changed || any_transform_control));
}
/** create a VisADGroup scene graph for Data in links[0];
a substitute for doTransform() without and Java3D classes
in its signature */
public boolean fakeTransform() throws VisADException, RemoteException {
// System.out.println("NodeRendererJ3D.doTransform enabled = " + enable_transform);
// don't do work unless requested by the client
if (!enable_transform) return true;
enable_transform = false;
/*
Vector map_vector = getDisplay().getMapVector();
Enumeration maps = map_vector.elements();
while (maps.hasMoreElements()) {
ScalarMap map = (ScalarMap) maps.nextElement();
double[] range = map.getRange();
Control control = map.getControl();
System.out.println(map + " " + ((float) range[0]) + " " + ((float) range[1]));
System.out.println(" " + control);
}
*/
VisADGroup branch = new VisADGroup();
DataDisplayLink[] Links = getLinks();
if (Links == null || Links.length == 0) {
return false;
}
DataDisplayLink link = Links[0];
ShadowTypeJ3D type = (ShadowTypeJ3D) link.getShadow();
// initialize valueArray to missing
int valueArrayLength = getDisplay().getValueArrayLength();
float[] valueArray = new float[valueArrayLength];
for (int i=0; i<valueArrayLength; i++) {
valueArray[i] = Float.NaN;
}
Data data;
try {
data = link.getData();
} catch (RemoteException re) {
if (visad.collab.CollabUtil.isDisconnectException(re)) {
getDisplay().connectionFailed(this, link);
removeLink(link);
return false;
}
throw re;
}
if (data == null) {
branch = null;
addException(
new DisplayException("Data is null: NodeRendererJ3D.doTransform"));
}
else {
link.start_time = System.currentTimeMillis();
link.time_flag = false;
type.preProcess();
boolean post_process;
try {
// transform data into a depiction under branch
post_process = type.doTransform(branch, data, valueArray,
link.getDefaultValues(), this);
} catch (RemoteException re) {
if (visad.collab.CollabUtil.isDisconnectException(re)) {
getDisplay().connectionFailed(this, link);
removeLink(link);
return false;
}
throw re;
}
if (post_process) type.postProcess(branch);
}
link.clearData();
// send VisADGroup scene graph in branch back to client
if (agent != null) {
agent.sendToClient(branch);
System.out.println("scene graph sent to client");
}
return true;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("NodeRendererJ3D");
}
public static void main(String args[])
throws VisADException, RemoteException {
DisplayImpl display =
new DisplayImplJ3D("display", new NodeDisplayRendererJ3D(),
DisplayImplJ3D.TRANSFORM_ONLY);
// create JFrame (i.e., a window) for display and slider
JFrame frame = new JFrame("test NodeRendererJ3D");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
// create JPanel in JFrame
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setAlignmentY(JPanel.TOP_ALIGNMENT);
panel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
frame.getContentPane().add(panel);
// add display to JPanel
// panel.add(display.getComponent());
// set size of JFrame and make it visible
frame.setSize(500, 500);
frame.setVisible(true);
}
}