diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/connections/paraview/ParaViewConnectionAdapter.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/connections/paraview/ParaViewConnectionAdapter.java index da916dd44..3e44ccb07 100644 --- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/connections/paraview/ParaViewConnectionAdapter.java +++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/connections/paraview/ParaViewConnectionAdapter.java @@ -114,87 +114,6 @@ public boolean setConnectionProperties(List row) { return changed; } - /** - * Creates a new view for rendering a different file or another - * representation of a file. - * - * @return The ID of the new view, or -1 if one could not be created. - */ - protected int createView() { - int viewId = -1; - - // Attempt to create a new view. If successful, its ID should be added - // to the set of view IDs. - try { - viewId = getConnection().createView().get(); - if (viewId >= 0) { - viewIds.add(viewId); - } - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - - return viewId; - } - - /** - * Opens the file at the specified path inside the view with the specified - * ID. This creates a ParaView file proxy corresponding to the file. - * - * @param viewId - * The ID of the view that will render the file. This must be a - * valid view ID previously returned by {@link #createView()}. - * @param fullPath - * The full path to the file on the client connection's machine. - * @return The ID of the file proxy, or -1 if one could not be created. - */ - protected int createFileProxy(int viewId, String fullPath) { - int fileId = -1; - - if (viewIds.contains(viewId)) { - - // Determine the relative path based on the current data directory - // for the connection. - final String relativePath = findRelativePath(fullPath); - - VtkWebClient client = getConnection(); - List args = new ArrayList(); - JSONObject object; - - // Try to open the file. - args.add(relativePath); - try { - // Open a view in order to read the file. - viewId = client.createView().get(); - - // Create a proxy reader using the default settings, then pull - // the ID of the created proxy if it exists. - object = client.call("pv.proxy.manager.create.reader", args) - .get(); - if (object.has("id")) { - fileId = object.getInt("id"); - } - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - } - - return fileId; - } - - /** - * Determines the representation proxy for the specified file proxy. - * - * @param fileId - * The ID of the file proxy. - * @return The ID of the file's representation proxy, or -1 if it could not - * be found. - */ - protected int findRepresentationProxy(int fileId) { - // TODO - return -1; - } - /** * Determines the relative path for the full path with respect to the client * connection's data directory. @@ -203,9 +122,11 @@ protected int findRepresentationProxy(int fileId) { * The full path to the file. * @return The relative path, or null if it could not be determined. */ - private String findRelativePath(String fullPath) { + public String findRelativePath(String fullPath) { String relativePath = null; + // TODO Move responsibility for this to the python code. + VtkWebClient client = getConnection(); List args = new ArrayList(); JSONObject object; diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java index 51d298e4c..93c691f31 100644 --- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java +++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlot.java @@ -17,7 +17,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; import org.eclipse.ice.viz.service.PlotRender; import org.eclipse.ice.viz.service.connections.ConnectionPlot; @@ -47,6 +46,8 @@ public class ParaViewPlot extends ConnectionPlot { * The ID of a view that was created in order to read the file contents. */ private int viewId = -1; + private int fileId = -1; + private int repId = -1; /** * The default constructor. @@ -67,11 +68,14 @@ public ParaViewPlot(ParaViewVizService vizService) { */ @Override protected PlotRender createPlotRender(Composite parent) { - // Reset the view ID to -1 every time so that the same view is not used - // twice. + // Reset the view IDs so that the same view is not used twice. int viewId = this.viewId; + int fileId = this.fileId; + int repId = this.repId; this.viewId = -1; - return new ParaViewPlotRender(parent, this, viewId); + this.fileId = -1; + this.repId = -1; + return new ParaViewPlotRender(parent, this, viewId, fileId, repId); } /* @@ -80,122 +84,61 @@ protected PlotRender createPlotRender(Composite parent) { * @see org.eclipse.ice.viz.service.MultiPlot#getPlotTypes(java.net.URI) */ @Override - protected Map getPlotTypes(URI file) throws IOException, + protected Map findPlotTypes(URI file) throws IOException, Exception { + // Set up the default return value. Map plotTypes = new HashMap(); - // Determine the relative path of the file from the ParaView web - // client's working directory. - String relativePath = getRelativePath(file.getPath()); - - System.out.println("Relative path: " + relativePath); - if (relativePath != null) { - int proxyId = openFile(relativePath); - System.out.println("The file proxy id: " + proxyId); - - // Get the file proxy's properties from the file. - VtkWebClient client = getConnectionAdapter().getConnection(); - JSONObject object; - JSONArray array; - List args = new ArrayList(1); - args.add(proxyId); - try { - object = client.call("pv.proxy.manager.get", args).get(); - // Get the "ui" JSON array from the proxy's properties. This - // contains the names of all data sets that can be displayed in - // the plot. - if (object.has("ui")) { - array = object.getJSONArray("ui"); - - // Determine all plot categories and their types. - for (int i = 0; i < array.length(); i++) { - object = array.getJSONObject(i); - - // Determine the plot category and its allowed types. - String name = object.getString("name"); - JSONArray valueArray = object.getJSONArray("values"); - String[] values = new String[valueArray.length()]; - for (int j = 0; j < values.length; j++) { - values[j] = valueArray.getString(j); - } - - // Store the plot category and types in the map. - plotTypes.put(name, values); - } - } - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - } - - return plotTypes; - } + ParaViewConnectionAdapter adapter = getParaViewConnectionAdapter(); + VtkWebClient client = adapter.getConnection(); - private String getRelativePath(String fullPath) { - String relativePath = null; - - VtkWebClient client = getConnectionAdapter().getConnection(); List args = new ArrayList(); JSONObject object; - args.add("."); - try { - object = client.call("file.server.directory.list", args).get(); - if (object != null) { - String directory = object.getJSONArray("path").getString(0); - System.out.println("The directory is: " + directory); - - // If the path is indeed a full path, we need to determine its - // relative path. - if (fullPath.startsWith("/")) { - // Determine the path to the base directory. - relativePath = ""; - String[] split = directory.split("/"); - for (int i = 0; i < split.length; i++) { - if (!split[i].trim().isEmpty()) { - relativePath += "../"; - } - } - // Add in the rest of the full path, excluding the initial - // forward slash. - if (fullPath.length() > 1) { - relativePath += fullPath.substring(1); - } - } else { - relativePath = fullPath; - } + // Open the file. We *have* to create a new view to open the file. Use + // the custom server method, as the default ParaViewWeb method uses the + // currently active view. + args.clear(); + args.add(adapter.findRelativePath(file.getPath())); + object = client.call("createView", args).get(); + viewId = object.getInt("viewId"); + fileId = object.getInt("proxyId"); + repId = object.getInt("repId"); + + // Read the contents of the file to populate the map of plot types. + args.clear(); + args.add(fileId); + object = client.call("pv.proxy.manager.get", args).get(); + // Get the "ui" JSON array from the proxy's properties. This contains + // the names of all data sets that can be displayed in the plot. + JSONArray array = object.getJSONArray("ui"); + + // Determine all plot categories and their types. + for (int i = 0; i < array.length(); i++) { + object = array.getJSONObject(i); + + // Determine the plot category and its allowed types. + String name = object.getString("name"); + JSONArray valueArray = object.getJSONArray("values"); + String[] values = new String[valueArray.length()]; + for (int j = 0; j < values.length; j++) { + values[j] = valueArray.getString(j); } - } catch (InterruptedException e) { - } catch (ExecutionException e) { - } - - return relativePath; - } - - private int openFile(String relativePath) { - int proxyId = -1; - VtkWebClient client = getConnectionAdapter().getConnection(); - List args = new ArrayList(); - JSONObject object; - - args.add(relativePath); - try { - // Open a view in order to read the file. - viewId = client.createView().get(); - - object = client.call("pv.proxy.manager.create.reader", args).get(); - if (object.has("id")) { - proxyId = object.getInt("id"); - } - } catch (InterruptedException e) { - } catch (ExecutionException e) { + // Store the plot category and types in the map. + plotTypes.put(name, values); } - return proxyId; + return plotTypes; } + /** + * Gets the connection adapter for the associated connection cast as a + * {@link ParaViewConnectionAdapter}. + * + * @return The associated connection adapter. + */ protected ParaViewConnectionAdapter getParaViewConnectionAdapter() { return (ParaViewConnectionAdapter) getConnectionAdapter(); } diff --git a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java index e4d7ff142..d584134eb 100644 --- a/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java +++ b/src/org.eclipse.ice.viz.service.paraview/src/org/eclipse/ice/viz/service/paraview/ParaViewPlotRender.java @@ -22,6 +22,8 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.ToolBar; +import org.json.JSONArray; +import org.json.JSONObject; import com.kitware.vtk.web.VtkWebClient; import com.kitware.vtk.web.util.InteractiveRenderPanel; @@ -38,9 +40,9 @@ public class ParaViewPlotRender extends ConnectionPlotRender { private String plotCategory; private String plotType; - private int id; - private int repId; private int viewId; + private int fileId; + private int repId; /** * The default constructor. @@ -52,7 +54,7 @@ public class ParaViewPlotRender extends ConnectionPlotRender { * The rendered ConnectionPlot. This cannot be changed. */ public ParaViewPlotRender(Composite parent, ParaViewPlot plot) { - this(parent, plot, -1); + this(parent, plot, -1, -1, -1); } /** @@ -67,16 +69,23 @@ public ParaViewPlotRender(Composite parent, ParaViewPlot plot) { * @param viewId * The ID of the view that was created to read the file's * contents, or -1 to indicate that a view has not been created. + * @param repId + * The ID of the representation (i.e., the render properties) of + * the file. */ - public ParaViewPlotRender(Composite parent, ParaViewPlot plot, int viewId) { + public ParaViewPlotRender(Composite parent, ParaViewPlot plot, int viewId, + int fileId, int repId) { super(parent, plot); ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); readLock = lock.readLock(); writeLock = lock.writeLock(); - // All negative IDs should be reverted to -1. - this.viewId = (viewId < 0 ? -1 : viewId); + this.viewId = viewId; + this.fileId = fileId; + this.repId = repId; + + return; } /** @@ -128,6 +137,31 @@ public void setPlotType(String type) { protected Composite createPlotComposite(Composite parent, int style, VtkWebClient connection) throws Exception { + // Create a new view on the ParaView server if one does not already + // exist. We will need the corresponding view, file proxy, and + // representation proxy IDs. + if (viewId < 0 || fileId < 0 || repId < 0) { + String fullPath = ((ParaViewPlot) plot) + .getParaViewConnectionAdapter().findRelativePath( + plot.getDataSource().getPath()); + + // Create a new view from the file and get its associated IDs. + List args = new ArrayList(); + JSONObject object; + args.add(fullPath); + object = connection.call("createView", args).get(); + viewId = object.getInt("viewId"); + fileId = object.getInt("proxyId"); + repId = object.getInt("repId"); + + // Throw an exception if a view could not be created for the file. + if (viewId < 0 || fileId < 0 || repId < 0) { + throw new Exception("IPlot error: " + + "The file could not be rendered with " + + plot.getVizService().getName() + "."); + } + } + // Create a container to hold a ToolBar and the ParaView widget. Composite plotContainer = new Composite(parent, style); plotContainer.setBackground(parent.getBackground()); @@ -154,12 +188,6 @@ protected Composite createPlotComposite(Composite parent, int style, | SWT.DOUBLE_BUFFERED); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - // Create a new view on the ParaView server if one does not already - // exist. - if (viewId < 0) { - viewId = connection.createView().get(); - } - // Create the ParaView widget. final InteractiveRenderPanel renderPanel = new InteractiveRenderPanel( connection, viewId, 4, 80, 1); @@ -195,10 +223,12 @@ protected void updatePlotComposite(Composite plotComposite, // TODO Update the contents of the ParaView widget if necessary. boolean plotTypeChanged = false; + String category = null; + String type = null; readLock.lock(); try { - String category = getPlotCategory(); - String type = getPlotType(); + category = getPlotCategory(); + type = getPlotType(); if (category != null && !category.equals(plotCategory)) { plotCategory = category; @@ -212,10 +242,140 @@ protected void updatePlotComposite(Composite plotComposite, readLock.unlock(); } - if (plotTypeChanged) { - + final String plotType = "Battery_/TemperatureP1"; + + // if (plotTypeChanged) { + List args = new ArrayList(); + JSONObject object; + + // Make sure this view is the active one. + args.add(viewId); + connection.call("activateView", args).get(); + + // Set the representation proxy to show the mesh as + // "Surface With Edges". + args.clear(); + JSONArray updatedProperties = new JSONArray(); + JSONObject repProperty = new JSONObject(); + repProperty.put("id", Integer.toString(repId)); + repProperty.put("name", "Representation"); + repProperty.put("value", "Surface"); + updatedProperties.put(repProperty); + + // Update the "status" of the mesh/material/cell/point arrays. + // For the silo file, we want to select Battery_/TemperatureP1. + JSONObject pointStatusProperty = new JSONObject(); + pointStatusProperty.put("id", Integer.toString(fileId)); + pointStatusProperty.put("name", "PointArrayStatus"); + JSONArray pointArrays = new JSONArray(); + pointArrays.put(plotType); + pointStatusProperty.put("value", pointArrays); + updatedProperties.put(pointStatusProperty); + + // Update the properties that were configured. + args.add(updatedProperties); + object = connection.call("pv.proxy.manager.update", args).get(); + if (!object.getBoolean("success")) { + System.out.println("Failed to set the representation: "); + JSONArray array = object.getJSONArray("errorList"); + for (int i = 0; i < array.length(); i++) { + System.out.println(array.get(i)); + } } + // Set the representation to color based on the plot type. + args.clear(); + args.add(Integer.toString(repId)); + args.add("ARRAY"); + args.add("POINTS"); + args.add(plotType); + args.add("Magnitude"); + args.add(0); + args.add(true); + object = connection.call("pv.color.manager.color.by", args).get(); + + // Set the visibility of the legend to true. + args.clear(); + JSONObject legendVisibilities = new JSONObject(); + legendVisibilities.put(Integer.toString(fileId), true); + args.add(legendVisibilities); + object = connection.call( + "pv.color.manager.scalarbar.visibility.set", args) + .get(); + System.out.println(object.toString(4)); + + // Auto-scale the color map to the data. + args.clear(); + JSONObject scaleOptions = new JSONObject(); + scaleOptions.put("type", "data"); + scaleOptions.put("proxyId", fileId); + args.add(scaleOptions); + object = connection.call( + "pv.color.manager.rescale.transfer.function", args) + .get(); + System.out.println(object.toString(4)); + + // // ---- Set the plot representation style. ---- // + // // Set the representation proxy to show the mesh as + // // "Surface With Edges". + // args.clear(); + // JSONArray updatedProperties = new JSONArray(); + // JSONObject repProperty = new JSONObject(); + // repProperty.put("id", Integer.toString(repId)); + // repProperty.put("name", "Representation"); + // repProperty.put("value", "Surface"); + // updatedProperties.put(repProperty); + // + // // Update the "status" of the mesh/material/cell/point arrays. + // // For the silo file, we want to select Battery_/TemperatureP1. + // JSONObject pointStatusProperty = new JSONObject(); + // pointStatusProperty.put("id", Integer.toString(fileId)); + // pointStatusProperty.put("name", "PointArrayStatus"); + // JSONArray pointArrays = new JSONArray(); + // pointArrays.put("Battery_/TemperatureP1"); + // pointStatusProperty.put("value", pointArrays); + // updatedProperties.put(pointStatusProperty); + // + // // Update the properties that were configured. + // args.add(updatedProperties); + // object = connection.call("pv.proxy.manager.update", args).get(); + // if (!object.getBoolean("success")) { + // System.out.println("Failed to set the representation: "); + // JSONArray array = object.getJSONArray("errorList"); + // for (int i = 0; i < array.length(); i++) { + // System.out.println(array.get(i)); + // } + // } + // // -------------------------------------------- // + // + // // ---- Set the plot type via the ColorManager. ---- // + // args.clear(); + // args.add(Integer.toString(repId)); // The rep ID to update. + // args.add("ARRAY"); // The "color mode". + // args.add("POINTS"); // The "array location". + // args.add("Battery_/TemperatureP1"); // The name of the array to plot, + // in this case the + // // plot type. The category does not need to be + // // specified. + // args.add("Magnitude"); // The default "vector mode". + // args.add(0); // The default "vector component". + // args.add(true); // This is supposed to rescale the colors. + // + // // Send these arguments to update the data set that the view plots. + // connection.call("pv.color.manager.color.by", args).get(); + // + // // Auto-scale the color map to the data. + // // args.clear(); + // // JSONObject scaleOptions = new JSONObject(); + // // scaleOptions.put("type", "data"); + // // scaleOptions.put("proxyId", fileId); + // // args.add(scaleOptions); + // // connection.call("pv.color.manager.rescale.transfer.function", + // // args) + // // .get(); + // // ------------------------------------------------- // + // } + return; } diff --git a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java index ab392a96a..51739c229 100644 --- a/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java +++ b/src/org.eclipse.ice.viz.service/src/org/eclipse/ice/viz/service/MultiPlot.java @@ -226,7 +226,7 @@ public void setDataSource(URI file) throws NullPointerException, } // Get the list of new plot types from the sub-class implementation. - Map newPlotTypes = getPlotTypes(file); + Map newPlotTypes = findPlotTypes(file); // If empty, throw an IllegalArgumentException. if (newPlotTypes.isEmpty()) { @@ -246,12 +246,17 @@ public void setDataSource(URI file) throws NullPointerException, } /** + * Note: This method is called automatically in + * {@link #setDataSource(URI)}. Implementations should always query the + * file. + *

* This operation returns a simple map of plot types that can be created by * the IPlot using its data source. The map is meant to have a structure * where each individual key is a type of plot - mesh, scalar, line, etc. - * with a list of values of all of the plots it can create of that given * type from the data source. For example, for a CSV file with three columns * x, y1, y2, y3, the map might be: + *

*

* key | value
* line | "x vs y1", "x vs y2", "x vs y3"
@@ -267,7 +272,7 @@ public void setDataSource(URI file) throws NullPointerException, * @throws Exception * if there is some other unspecified problem with the file */ - protected abstract Map getPlotTypes(URI file) + protected abstract Map findPlotTypes(URI file) throws IOException, Exception; /**