From: adam Date: Mon, 26 Nov 2007 03:43:57 +0000 (-0800) Subject: init X-Git-Url: http://git.megacz.com/?p=anneal.git;a=commitdiff_plain;h=77132d13c4434fa3e320d4516e98c1d8a7df21cc;ds=sidebyside init darcs-hash:20071126034357-5007d-538cebe4569498197ec1e1a53f79348b55540f15.gz --- 77132d13c4434fa3e320d4516e98c1d8a7df21cc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a9c9949 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +all: + mkdir -p build + javac -d build `find src -name \*.java` + java -cp build Geom diff --git a/src/Geom.java b/src/Geom.java new file mode 100644 index 0000000..fec07b5 --- /dev/null +++ b/src/Geom.java @@ -0,0 +1,164 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; + +public class Geom implements GLEventListener { + + public static StlFile stlf = null; + + /** + * Take care of initialization here. + */ + public void init(GLAutoDrawable gld) { + GL gl = gld.getGL(); + GLU glu = new GLU(); + gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + gl.glViewport(0, 0, 500, 300); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + //glu.gluOrtho2D(0.0, 500.0, 0.0, 300.0); + display(gld); + } + + + /** + * Take care of drawing here. + */ + public void display(GLAutoDrawable drawable) { + float red = 0.0f; + float green = 0.0f; + float blue = 0.0f; + GL gl = drawable.getGL(); + gl.glClear(GL.GL_COLOR_BUFFER_BIT); + gl.glPointSize(5.0f); + + for(int i=0; i true o binary -> false + private String fileName = null; + + // Arrays with coordinates and normals + // Needed for reading ASCII files because its size is unknown until the end + private ArrayList coordList; // Holds Point3f + private ArrayList normList; // Holds Vector3f + + // GeometryInfo needs Arrays + public Point3f[] coordArray = null; + public Vector3f[] normArray = null; + + // Needed because TRIANGLE_STRIP_ARRAY + // As the number of strips = the number of faces it's filled in objectToVectorArray + public int[] stripCounts = null; + + // Default = Not available + private String objectName=new String("Not available"); + + /** + * Constructor + */ + public StlFile() + { + } + + /** + * Method that reads the EOL + * Needed for verifying that the file has a correct format + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readEOL(StlFileParser parser) + { + try{ + parser.nextToken(); + } + catch (IOException e) + { + System.err.println("IO Error on line " + parser.lineno() + ": " + e.getMessage()); + } + if(parser.ttype != StlFileParser.TT_EOL) + { + System.err.println("Format Error:expecting End Of Line on line " + parser.lineno()); + } + } + + /** + * Method that reads the word "solid" and stores the object name. + * It also detects what kind of file it is + * TO-DO: + * 1.- Better way control of exceptions? + * 2.- Better way to decide between Ascii and Binary? + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readSolid(StlFileParser parser) + { + if( !parser.sval.equals("solid")) + { + //System.out.println("Expecting solid on line " + parser.lineno()); + // If the first word is not "solid" then we consider the file is binary + // Can give us problems if the comment of the binary file begins by "solid" + this.setAscii(false); + } + else // It's an ASCII file + { + try{ + parser.nextToken(); + } + catch (IOException e) + { + System.err.println("IO Error on line " + parser.lineno() + ": " + e.getMessage()); + } + if( parser.ttype != StlFileParser.TT_WORD) + { + // Is the object name always provided??? + System.err.println("Format Error:expecting the object name on line " + parser.lineno()); + } + else + { // Store the object Name + this.setObjectName(new String(parser.sval)); + if(DEBUG==1) + { + System.out.println("Object Name:" + this.getObjectName().toString()); + } + this.readEOL(parser); + } + } + }//End of readSolid + + /** + * Method that reads a normal + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readNormal(StlFileParser parser) + { + Vector3f v = new Vector3f(); + + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("normal"))) + { + System.err.println("Format Error:expecting 'normal' on line " + parser.lineno()); + } + else + { + if (parser.getNumber()) + { + v.x=(float)parser.nval; + + if(DEBUG==1) + { + System.out.println("Normal:"); + System.out.print("X=" + v.x + " "); + } + + if (parser.getNumber()) + { + v.y=(float)parser.nval; + if(DEBUG==1) + System.out.print("Y=" + v.y + " "); + + if (parser.getNumber()) + { + v.z=(float)parser.nval; + if(DEBUG==1) + System.out.println("Z=" + v.z); + + // We add that vector to the Normal's array + this.normList.add(v); + this.readEOL(parser); + } + else System.err.println("Format Error:expecting coordinate on line " + parser.lineno()); + } + else System.err.println("Format Error:expecting coordinate on line " + parser.lineno()); + } + else System.err.println("Format Error:expecting coordinate on line " + parser.lineno()); + } + }// End of Read Normal + + /** + * Method that reads the coordinates of a vector + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readVertex(StlFileParser parser) + { + Point3f p = new Point3f(); + + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("vertex"))) + { + System.err.println("Format Error:expecting 'vertex' on line " + parser.lineno()); + } + else + { + if (parser.getNumber()) + { + p.x=(float)parser.nval; + + if(DEBUG==1) + { + System.out.println("Vertex:"); + System.out.print("X=" + p.x + " "); + } + + if (parser.getNumber()) + { + p.y=(float)parser.nval; + if(DEBUG==1) + System.out.print("Y=" + p.y + " "); + + if (parser.getNumber()) + { + p.z=(float)parser.nval; + if(DEBUG==1) + System.out.println("Z=" + p.z); + + // We add that vertex to the array of vertex + coordList.add(p); + readEOL(parser); + } + else System.err.println("Format Error: expecting coordinate on line " + parser.lineno()); + } + else System.err.println("Format Error: expecting coordinate on line " + parser.lineno()); + } + else System.err.println("Format Error: expecting coordinate on line " + parser.lineno()); + } + }//End of read vertex + + /** + * Method that reads "outer loop" and then EOL + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readLoop(StlFileParser parser) + { + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("outer"))) + { + System.err.println("Format Error:expecting 'outer' on line " + parser.lineno()); + } + else + { + try{ + parser.nextToken(); + } + catch (IOException e) + { + System.err.println("IO error on line " + parser.lineno() + ": " + e.getMessage()); + } + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("loop"))) + { + System.err.println("Format Error:expecting 'loop' on line " + parser.lineno()); + } + else readEOL(parser); + } + }//End of readLoop + + /** + * Method that reads "endloop" then EOL + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readEndLoop(StlFileParser parser) + { + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("endloop"))) + { + System.err.println("Format Error:expecting 'endloop' on line " + parser.lineno()); + } + else readEOL(parser); + }//End of readEndLoop + + /** + * Method that reads "endfacet" then EOL + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readEndFacet(StlFileParser parser) + { + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("endfacet"))) + { + System.err.println("Format Error:expecting 'endfacet' on line " + parser.lineno()); + } + else readEOL(parser); + }//End of readEndFacet + + /** + * Method that reads a face of the object + * (Cares about the format) + * + * @param parser The file parser. An instance of StlFileParser. + */ + private void readFacet(StlFileParser parser) + { + if(!(parser.ttype==StlFileParser.TT_WORD && parser.sval.equals("facet"))) + { + System.err.println("Format Error:expecting 'facet' on line " + parser.lineno()); + } + else + { + try{ + parser.nextToken(); + readNormal(parser); + + parser.nextToken(); + readLoop(parser); + + parser.nextToken(); + readVertex(parser); + + parser.nextToken(); + readVertex(parser); + + parser.nextToken(); + readVertex(parser); + + parser.nextToken(); + readEndLoop(parser); + + parser.nextToken(); + readEndFacet(parser); + } + catch (IOException e) + { + System.err.println("IO Error on line " + parser.lineno() + ": " + e.getMessage()); + } + } + }// End of readFacet + + /** + * Method that reads a face in binary files + * All binary versions of the methods end by 'B' + * As in binary files we can read the number of faces, we don't need + * to use coordArray and normArray (reading binary files should be faster) + * + * @param in The ByteBuffer with the data of the object. + * @param index The facet index + * + * @throws IOException + */ + private void readFacetB(ByteBuffer in, int index) throws IOException + { + //File structure: Normal Vertex1 Vertex2 Vertex3 + Vector3f normal = new Vector3f(); + Point3f vertex = new Point3f(); + + if(DEBUG==1) + System.out.println("Reading face number " + index); + + // Read the Normal + normArray[index]=new Vector3f(); + normArray[index].x=in.getFloat(); + normArray[index].y=in.getFloat(); + normArray[index].z=in.getFloat(); + + if(DEBUG==1) + System.out.println("Normal: X=" + normArray[index].x + " Y=" + normArray[index].y + " Z=" + normArray[index].z); + + // Read vertex1 + coordArray[index*3] = new Point3f(); + coordArray[index*3].x=in.getFloat(); + coordArray[index*3].y=in.getFloat(); + coordArray[index*3].z=in.getFloat(); + + if(DEBUG==1) + System.out.println("Vertex 1: X=" + coordArray[index*3].x + " Y=" + coordArray[index*3].y + " Z=" + coordArray[index*3].z); + + // Read vertex2 + coordArray[index*3+1] = new Point3f(); + coordArray[index*3+1].x=in.getFloat(); + coordArray[index*3+1].y=in.getFloat(); + coordArray[index*3+1].z=in.getFloat(); + + if(DEBUG==1) + System.out.println("Vertex 2: X=" + coordArray[index*3+1].x + " Y=" + coordArray[index*3+1].y + " Z=" + coordArray[index*3+1].z); + + // Read vertex3 + coordArray[index*3+2] = new Point3f(); + coordArray[index*3+2].x=in.getFloat(); + coordArray[index*3+2].y=in.getFloat(); + coordArray[index*3+2].z=in.getFloat(); + + if(DEBUG==1) + System.out.println("Vertex 3: X=" + coordArray[index*3+2].x + " Y=" + coordArray[index*3+2].y + " Z=" + coordArray[index*3+2].z); + + }// End of readFacetB + + /** + * Method for reading binary files + * Execution is completly different + * It uses ByteBuffer for reading data and ByteOrder for retrieving the machine's endian + * (Needs JDK 1.4) + * + * TO-DO: + * 1.-Be able to read files over Internet + * 2.-If the amount of data expected is bigger than what is on the file then + * the program will block forever + * + * @param file The name of the file + * + * @throws IOException + */ + private void readBinaryFile(String file) throws IOException + { + FileInputStream data; // For reading the file + ByteBuffer dataBuffer; // For reading in the correct endian + byte[] Info=new byte[80]; // Header data + byte[] Array_number= new byte[4]; // Holds the number of faces + byte[] Temp_Info; // Intermediate array + + int Number_faces; // First info (after the header) on the file + + if(DEBUG==1) + System.out.println("Machine's endian: " + ByteOrder.nativeOrder()); + + // Get file's name + if(fromUrl) + { + // FileInputStream can only read local files!? + System.out.println("This version doesn't support reading binary files from internet"); + } + else + { // It's a local file + data = new FileInputStream(file); + + // First 80 bytes aren't important + if(80 != data.read(Info)) + { // File is incorrect + //System.out.println("Format Error: 80 bytes expected"); + throw new IncorrectFormatException(); + } + else + { // We must first read the number of faces -> 4 bytes int + // It depends on the endian so.. + + data.read(Array_number); // We get the 4 bytes + dataBuffer = ByteBuffer.wrap(Array_number); // ByteBuffer for reading correctly the int + dataBuffer.order(ByteOrder.nativeOrder()); // Set the right order + Number_faces = dataBuffer.getInt(); + + Temp_Info = new byte[50*Number_faces]; // Each face has 50 bytes of data + + data.read(Temp_Info); // We get the rest of the file + + dataBuffer = ByteBuffer.wrap(Temp_Info); // Now we have all the data in this ByteBuffer + dataBuffer.order(ByteOrder.nativeOrder()); + + if(DEBUG==1) + System.out.println("Number of faces= " + Number_faces); + + // We can create that array directly as we know how big it's going to be + coordArray = new Point3f[Number_faces*3]; // Each face has 3 vertex + normArray = new Vector3f[Number_faces]; + stripCounts = new int[Number_faces]; + + for(int i=0;i 0 ; i--) { + String a = stok.nextToken(); + sb.append(a); + sb.append(java.io.File.separator); + } + setBasePath(sb.toString()); + } // End of setBasePathFromFilename + + public int getFlags() + { + return flag; + } + + public void setFlags(int parm) + { + this.flag=parm; + } + + public boolean getAscii() + { + return this.Ascii; + } + + public void setAscii(boolean tipo) + { + this.Ascii = tipo; + } + + + public String getFileName() + { + return this.fileName; + } + + public void setFileName(String filename) + { + this.fileName=new String(filename); + } + + + public String getObjectName() + { + return this.objectName; + } + + public void setObjectName(String name) + { + this.objectName = name; + } + +} // End of package stl_loader \ No newline at end of file diff --git a/src/StlFileParser.java b/src/StlFileParser.java new file mode 100644 index 0000000..8743cca --- /dev/null +++ b/src/StlFileParser.java @@ -0,0 +1,99 @@ +import java.io.StreamTokenizer; +import java.io.Reader; +import java.io.IOException; + +/** + * Title: STL Loader + * Description: STL files loader (Supports ASCII and binary files) for Java3D + * Needs JDK 1.4 due to endian problems + * Copyright: Copyright (c) 2001 + * Company: Universidad del Pais Vasco (UPV/EHU) + * @author: Carlos Pedrinaci Godoy + * @version 1.0 + * + * Contact : xenicp@yahoo.es + * + * STL FILE PARSER: + * Extends StreamTokenizer + * For Ascii files + * Each token returned is checked in StlFile.java + * Format of an ASCII STL file: + * + * solid /users/vis/dru/wedge.stl + * facet normal -1 0 0 + * outer loop + * vertex 0.005 1 0 + * vertex 0 0.543 0 + * vertex 0.453 1 1 + * endloop + * endfacet + * . + * . + * . + * endsolid /users/vis/dru/wedge.stl + * + * That Class is necessary because scientific numbers are not correctly readed by Tokenizer + * we must then extend that class and define another getNumber + */ + +public class StlFileParser extends StreamTokenizer +{ + /** + * Constructor: object creation and setup + * + * @param r The Reader instance + */ + public StlFileParser(Reader r) + { + super(r); + setup(); + } + + /** + * Method that sets some params of the Tokenizer for reading the file correctly + */ + public void setup() + { + resetSyntax(); + eolIsSignificant(true); // The End Of Line is important + lowerCaseMode(true); + + // All printable ascii characters + wordChars('!', '~'); + + whitespaceChars(' ', ' '); + whitespaceChars('\n', '\n'); + whitespaceChars('\r', '\r'); + whitespaceChars('\t', '\t'); + }// End setup + + /** + * Gets a number from the stream. Note that we don't recognize + * numbers in the tokenizer automatically because numbers might be in + * scientific notation, which isn't processed correctly by + * StreamTokenizer. The number is returned in nval. + * + * @return boolean. + */ + boolean getNumber() + { + int t; + + try { + nextToken(); + if (ttype != TT_WORD) + throw new IOException("Expected number on line " + lineno()); + nval = (Double.valueOf(sval)).doubleValue(); + } + catch (IOException e) { + System.err.println(e.getMessage()); + return false; + } + catch (NumberFormatException e) { + System.err.println(e.getMessage()); + return false; + } + return true; + } // end of getNumber + +}// End of StlFileParser diff --git a/teapot.stl b/teapot.stl new file mode 100644 index 0000000..0c86f6d Binary files /dev/null and b/teapot.stl differ