/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2004, by :
* Corporate:
* EADS Corporate Research Center
* Individual:
* Nicolas Brodu
*
* $Id: XYZResultNode.java,v 1.1 2005/06/14 13:12:40 ogor Exp $
*
* Changes
* -------
* 01-Jun-2004 : Creation date (NB);
*
*/
package examples.syn3d.plugin.java3d;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import syn3d.base.ActiveNode;
/**
*
* This is an example node to handle files in X-Y-Z-Result format.
* This is a simple format, which can be loaded by programs like TecPlot.
*
* The format is plain text.
* The first 2 lines are information on the data (see load method). These include the number
* of points and number of triangles.
* Then, the values are given line by line :
* The X, Y, Z coordinates of a point, plus values associated to this point (ex: temperature, voltage...)
* An empty line then separates the definition of the triangles.
* The index of the previously defined points (starting from one) are given line by line,
* to from the 3 summits of the triangle.
*
*/
public class XYZResultNode extends ActiveNode {
/**
* File data in one big buffer.
* data[var][index] gives the value for a variable at the given index.
* First variables are assumed to be X, Y, Z coordinates
*/
double[][] data;
/** min and max values for each variable */
double[] min, max;
/** Variable names */
String[] names;
/**
* Triangle index of points in the data array.
* 3 consecutive entries describe one triangle with the XYZ data in the data array
* This is the standard indexed format for both Java3D and Xith3D
*/
int[] triangles;
/** This node needs a parent node to attach to */
public XYZResultNode(ActiveNode parent) {
super(parent);
}
/** Let's declare an action to load a file */
public List getActions() {
List actions = new ArrayList();
actions.add(0, "Load file");
return actions;
}
/** Do a previously declared action */
public void doAction(Object action) {
if (action.equals("Load file")) {
JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(new FileFilter() {
public boolean accept(File f) {
if (f.isDirectory()) return true;
String name = f.getName();
return name.toLowerCase().endsWith(".xyz");
}
public String getDescription() {
return "XYZ result files (*.xyz)";
}
});
int ret = chooser.showOpenDialog(null);
if (ret == JFileChooser.APPROVE_OPTION) {
try {
load(chooser.getSelectedFile());
} catch (IOException e) {
JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), "Can't load "+chooser.getSelectedFile(),JOptionPane.ERROR_MESSAGE);
return;
}
}
}
super.doAction(action);
}
/**
* Called from doAction => Load a file with the correct file format
* This Method should overriden by subclasses, so as to create 3D objects according
* to the data in the file.
*/
protected void load(File file) throws IOException {
if (file==null) return;
BufferedReader br = new BufferedReader(new FileReader(file));
// First line contains variable names
String variables = br.readLine();
// Parse the variables
StringTokenizer st = new StringTokenizer(variables.substring(variables.indexOf('=')+1),"\t ,;:");
// Allocate variable names
int numVars = st.countTokens();
names = new String[numVars];
for (int i=0; i<numVars; ++i) names[i] = st.nextToken();
// Second line is information on the data
String info = br.readLine();
// Parse the information
st = new StringTokenizer(info,"\t ,;:");
int numTri = 0;
int numPoints = 0;
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (token.startsWith("N=")) numPoints = Long.decode(token.substring(2)).intValue();
else if (token.startsWith("E=")) numTri = Long.decode(token.substring(2)).intValue();
}
// set up min and max
min = new double[numVars];
max = new double[numVars];
for (int d=0; d<numVars; ++d) {
min[d] = Double.POSITIVE_INFINITY;
max[d] = Double.NEGATIVE_INFINITY;
}
// Store file data
data = new double[numVars][numPoints];
for (int i=0; i<numPoints; ++i) {
st = new StringTokenizer(br.readLine(), " ");
if (st.countTokens() != numVars) throw new IOException("Invalid file format at line "+(i+3));
try {
for (int d=0; d<numVars; ++d) {
data[d][i] = Double.parseDouble(st.nextToken());
if (data[d][i]<min[d]) min[d] = data[d][i];
if (data[d][i]>max[d]) max[d] = data[d][i];
}
} catch (NumberFormatException e) {
throw new IOException("Invalid number format (should be a real number) at line "+(i+3)+": "+e.getLocalizedMessage());
}
}
// Store geometry (triangles)
triangles = new int[numTri*3];
for (int i=0; i<triangles.length; i+=3) {
String line = br.readLine();
while (line.trim().equals("")) line = br.readLine();
st = new StringTokenizer(line);
if (st.countTokens() != 3) {
System.out.println(st.countTokens()+": "+line);
throw new IOException("Invalid file format at line "+(i/3 + numPoints + 2));
}
try {
// indices are written from 1 in the file, stored from 0 in the array
triangles[i+0] = Integer.parseInt(st.nextToken()) - 1;
triangles[i+1] = Integer.parseInt(st.nextToken()) - 1;
triangles[i+2] = Integer.parseInt(st.nextToken()) - 1;
} catch (NumberFormatException e) {
throw new IOException("Invalid number format (should be an integer) at line "+(i/3 + numPoints + 2)+": "+e.getLocalizedMessage());
}
}
// Child classes overload and do their job
}
/**
* Shows the given result from the data file.
* variables are given in the file as X, Y, Z and a variable number of results to display for each point
* By default, the first variable is displayed. This function changes the variable to display
*/
public void showResult(int num) {
// Child classes overload and do their job
}
}