2 <?xml version='1.0' standalone='yes' ?>
\r
5 <name>Import GNU Triangulated Surface</name>
\r
6 <author>Enrique Perez</author>
\r
7 <version>1.0</version>
\r
8 <date>29-Apr-2008</date>
\r
10 This script imports GNU Triangulated Surfaces as triangle meshes.
\r
12 <licenseType>gpl</licenseType>
\r
17 Add a delete the last object of the scene undo record, to the scene.
\r
20 void addUndoRecord() {
\r
21 scene = window.getScene();
\r
22 undoAdd = new UndoRecord ( window, false, UndoRecord.DELETE_OBJECT, new Object[] { new Integer( scene.getNumObjects() - 1 ) } );
\r
23 window.setUndoRecord( undoAdd );
\r
26 int getSameVertexIndex( edgeFirst, edgeSecond )
\r
28 for ( int endpointIndex = 0; endpointIndex < 2; endpointIndex++ ) {
\r
29 endpoint = edgeFirst[ endpointIndex ];
\r
31 if ( endpoint == edgeSecond[ 0 ] ) {
\r
35 if ( endpoint == edgeSecond[ 1 ] ) {
\r
40 print( "Inconsistent GNU Triangulated Surface" );
\r
42 print( edgeSecond );
\r
47 Import GNU Triangulated Surface from a file.
\r
48 Quoted from http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE
\r
49 "All the lines beginning with GTS_COMMENTS (#!) are ignored. The first line contains three unsigned integers separated by spaces. The first integer is the number of vertices, nv, the second is the number of edges, ne and the third is the number of faces, nf.
\r
51 Follows nv lines containing the x, y and z coordinates of the vertices. Follows ne lines containing the two indices (starting from one) of the vertices of each edge. Follows nf lines containing the three ordered indices (also starting from one) of the edges of each face.
\r
53 The format described above is the least common denominator to all GTS files. Consistent with an object-oriented approach, the GTS file format is extensible. Each of the lines of the file can be extended with user-specific attributes accessible through the read() and write() virtual methods of each of the objects written (surface, vertices, edges or faces). When read with different object classes, these extra attributes are just ignored."
\r
56 void importFile( gnuFile )
\r
58 bufferedReader = new BufferedReader( new FileReader( gnuFile ) );
\r
59 Vector lineVector = new Vector();
\r
60 line = bufferedReader.readLine();
\r
61 name = gnuFile.getName();
\r
62 int lastIndexOfDot = name.lastIndexOf( '.' );
\r
64 if ( lastIndexOfDot > 0 ) {
\r
65 name = name.substring( 0, lastIndexOfDot );
\r
68 while ( line != null ) {
\r
70 if ( line.length() > 0 ) {
\r
71 firstCharacter = line.charAt( 0 );
\r
73 if ( firstCharacter != '#' && firstCharacter != '!' ) {
\r
74 lineVector.add( line );
\r
78 line = bufferedReader.readLine();
\r
81 splitLine = lineVector.get( 0 ).split( " " );
\r
82 int numberOfVertices = Integer.valueOf( splitLine[ 0 ] );
\r
83 int numberOfEdges = Integer.valueOf( splitLine[ 1 ] );
\r
84 int numberOfFaces = Integer.valueOf( splitLine[ 2 ] );
\r
85 edges = new int[ numberOfEdges ][ 2 ];
\r
86 faces = new int[ numberOfFaces ][ 3 ];
\r
87 vertices = new Vec3[ numberOfVertices ];
\r
89 for ( int vertexIndex = 0; vertexIndex < numberOfVertices; vertexIndex++ ) {
\r
90 line = lineVector.get( vertexIndex + 1 );
\r
91 splitLine = line.split( " " );
\r
92 vertex = new Vec3( Double.valueOf( splitLine[ 0 ] ), Double.valueOf( splitLine[ 1 ] ), Double.valueOf( splitLine[ 2 ] ) );
\r
93 vertices[ vertexIndex ] = vertex;
\r
96 int edgeStart = numberOfVertices + 1;
\r
98 for ( int edgeIndex = 0; edgeIndex < numberOfEdges; edgeIndex++ ) {
\r
99 line = lineVector.get( edgeIndex + edgeStart );
\r
100 splitLine = line.split( " " );
\r
101 int[] edge = { Integer.valueOf( splitLine[ 0 ] ) - 1, Integer.valueOf( splitLine[ 1 ] ) - 1 };
\r
102 edges[ edgeIndex ] = edge;
\r
105 int faceStart = edgeStart + numberOfEdges;
\r
107 for ( int faceIndex = 0; faceIndex < numberOfFaces; faceIndex++ ) {
\r
108 line = lineVector.get( faceIndex + faceStart );
\r
109 splitLine = line.split( " " );
\r
110 edgeFirst = edges[ Integer.valueOf( splitLine[ 0 ] ) - 1 ];
\r
111 edgeSecond = edges[ Integer.valueOf( splitLine[ 1 ] ) - 1 ];
\r
112 edgeThird = edges[ Integer.valueOf( splitLine[ 2 ] ) - 1 ];
\r
113 int[] vertexIndices = { getSameVertexIndex( edgeFirst, edgeSecond ), getSameVertexIndex( edgeSecond, edgeThird ), getSameVertexIndex( edgeThird, edgeFirst ) };
\r
114 faces[ faceIndex ] = vertexIndices;
\r
117 CoordinateSystem coordinateSystem = new CoordinateSystem();
\r
119 while ( window.getScene().getObject( name ) != null ) {
\r
123 mesh = new TriangleMesh ( vertices, faces );
\r
124 mesh.setSmoothingMethod( Mesh.NO_SMOOTHING );
\r
125 window.addObject( mesh, coordinateSystem, name, null );
\r
130 Import GNU Triangulated Surface from a file or from files in a directory.
\r
135 if ( openFileButton.getState() ) {
\r
136 importFile( file );
\r
140 filesInDirectory = file.getParentFile().listFiles();
\r
142 for ( int fileIndex = 0; fileIndex < filesInDirectory.length; fileIndex++ ) {
\r
143 directoryFile = filesInDirectory[ fileIndex ];
\r
144 String directoryFileName = directoryFile.getName();
\r
146 if ( directoryFileName.endsWith( ".gts" ) ) {
\r
147 importFile( directoryFile );
\r
153 Add radio button groups to the preference widgets.
\r
155 @param radioButtonGroups radio button groups which will be added to the memorable widgets
\r
156 @param widgetVector memorable widgets
\r
159 void preferencesAddRadioButtonGroups( RadioButtonGroup[] radioButtonGroups, Vector widgetVector )
\r
161 for ( int radioIndex = 0; radioIndex < radioButtonGroups.length; radioIndex++ ) {
\r
162 radioButtonGroup = radioButtonGroups[ radioIndex ];
\r
163 radioButtonGroupIterator = radioButtonGroup.getRadioButtons();
\r
165 while ( radioButtonGroupIterator.hasNext() ) {
\r
166 radioButton = radioButtonGroupIterator.next();
\r
167 preferencesAddWidgetWithString( radioButton, radioButton.getText(), widgetVector );
\r
173 Add widgets which have titles.
\r
175 @param widgets widgets which have titles
\r
176 @param widgetStrings widget titles
\r
177 @param widgetVector memorable widgets
\r
180 void preferencesAddWidgetsWithStrings( Widget[] widgets, String[] widgetStrings, Vector widgetVector )
\r
182 for ( int widgetIndex = 0; widgetIndex < widgets.length; widgetIndex++ ) {
\r
183 widget = widgets[ widgetIndex ];
\r
185 if ( widget instanceof BCheckBox || widget instanceof BOutline || widget instanceof BTextField || widget instanceof ValueField ) {
\r
186 preferencesAddWidgetWithString( widget, widgetStrings[ widgetIndex ], widgetVector );
\r
192 Give the widget a name and add it to the widget vector.
\r
194 @param widget widget which will be given a name
\r
195 @param widgetStrings widget name
\r
196 @param widgetVector memorable widgets
\r
199 void preferencesAddWidgetWithString( Widget widget, String widgetString, Vector widgetVector )
\r
201 widget.setName( widgetString );
\r
202 widgetVector.add( widget );
\r
206 Read widget settings from preferences file.
\r
208 @param preferencesFilename preferences filename
\r
209 @param widgetVector memorable widgets
\r
212 void preferencesRead( String preferencesFilename, Vector widgetVector )
\r
214 preferencesFile = new File( preferencesFilename );
\r
216 if ( !preferencesFile.canRead() ) {
\r
220 BufferedReader preferencesReader = new BufferedReader( new FileReader( preferencesFile ) );
\r
222 line = preferencesReader.readLine();
\r
224 while ( line != null ) {
\r
225 preferencesReadLine( line, widgetVector );
\r
226 line = preferencesReader.readLine();
\r
231 Read line of preferences and set widget to that line.
\r
233 @param line line of preferences
\r
234 @param widgetVector memorable widgets
\r
237 void preferencesReadLine( String line, Vector widgetVector )
\r
239 splitLine = line.split( "\t" );
\r
241 if ( splitLine.length < 2 ) {
\r
245 name = splitLine[ 0 ];
\r
247 for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) {
\r
248 widget = widgetVector.elementAt( widgetIndex );
\r
250 if ( widget.getName().equals( name ) ) {
\r
251 preferencesReadWidget( splitLine[ 1 ], widget );
\r
259 Set widget to preferences value.
\r
261 @param value preferences value
\r
262 @param widget widget to be set to value
\r
265 void preferencesReadWidget( String value, Widget widget )
\r
267 if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) {
\r
268 widget.setState( Boolean.valueOf( value ) );
\r
273 if ( widget instanceof BOutline ) { // it would be better to save the value instead of index because the list might change, but I'm lazy
\r
274 bList = widget.getContent().getContent();
\r
275 selectedIndex = Integer.valueOf( value );
\r
276 bList.setSelected( selectedIndex, true );
\r
277 bList.scrollToItem( selectedIndex );
\r
282 if ( widget instanceof BTextField ) {
\r
283 widget.setText( value );
\r
288 if ( widget instanceof ValueField ) {
\r
289 widget.setValue( Double.valueOf( value ) );
\r
294 Write widget settings to preferences file.
\r
296 @param preferencesFilename preferences filename
\r
297 @param widgetVector memorable widgets
\r
300 void preferencesWrite( String preferencesFilename, Vector widgetVector )
\r
302 preferencesFile = new File( preferencesFilename );
\r
304 if ( preferencesFile == null ) {
\r
305 print( "Can not write preferences to " + preferencesFilename );
\r
310 BufferedWriter preferencesWriter = new BufferedWriter( new FileWriter( preferencesFile ) );
\r
312 for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) {
\r
313 widget = widgetVector.elementAt( widgetIndex );
\r
314 preferencesWriteWidget( preferencesWriter, widget );
\r
317 //Close the output stream
\r
318 preferencesWriter.close();
\r
322 Write widget settings to line of preferences.
\r
324 @param preferencesWriter buffered preferences file writer
\r
325 @param widget widget to be written
\r
328 void preferencesWriteWidget( BufferedWriter preferencesWriter, Widget widget )
\r
330 widgetString = widget.getName() + "\t";
\r
332 if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) {
\r
333 preferencesWriter.write( widgetString + widget.getState().toString() + "\n" );
\r
338 if ( widget instanceof BOutline ) { // it would be better to save the value because the list might change, but I'm lazy
\r
339 BList bList = widget.getContent().getContent();
\r
340 bList = widget.getContent().getContent();
\r
341 preferencesWriter.write( widgetString + bList.getSelectedIndex().toString() + "\n" );
\r
346 if ( widget instanceof BTextField ) {
\r
347 preferencesWriter.write( widgetString + widget.getText() + "\n" );
\r
352 if ( widget instanceof ValueField ) {
\r
353 preferencesWriter.write( widgetString + widget.getValue().toString() + "\n" );
\r
357 // Set default parameters.
\r
358 directoryRadioButtonGroup = new RadioButtonGroup();
\r
359 openDirectoryButton = new BRadioButton( "Import All GNU Triangulated Surface Files in a Directory", false, directoryRadioButtonGroup );
\r
360 openFileButton = new BRadioButton( "Import File", true, directoryRadioButtonGroup );
\r
361 directoryGridContainer = new GridContainer( 1, 2 );
\r
362 directoryGridContainer.setDefaultLayout( new LayoutInfo( LayoutInfo.WEST, LayoutInfo.NONE, new Insets( 2, 2, 2, 2 ), null ) );
\r
363 directoryGridContainer.add( openDirectoryButton, 0, 0 );
\r
364 directoryGridContainer.add( openFileButton, 0, 1 );
\r
365 gnuSurfaceFilenameTextField = new BTextField( "" );
\r
366 String preferencesFilename = "import_gnu_triangulated_surface_preferences.csv";
\r
368 Widget[] widgets = new Widget[] { directoryGridContainer };
\r
369 String[] widgetStrings = new String[] { "Open File or Directory:" };
\r
371 // change the user interface parameters from default to preferences
\r
372 Vector widgetVector = new Vector();
\r
373 RadioButtonGroup[] radioButtonGroups = new RadioButtonGroup[] { directoryRadioButtonGroup };
\r
374 preferencesAddRadioButtonGroups( radioButtonGroups, widgetVector );
\r
375 preferencesAddWidgetsWithStrings( widgets, widgetStrings, widgetVector );
\r
376 preferencesAddWidgetWithString( gnuSurfaceFilenameTextField, "GCode Filename:", widgetVector );
\r
377 preferencesRead( preferencesFilename, widgetVector );
\r
379 dialog = new ComponentsDialog( window, "Import GNU Triangulated Surface File or Directory", widgets, widgetStrings );
\r
381 if ( !dialog.clickedOk() ) return;
\r
383 fileChooser = new BFileChooser( BFileChooser.OPEN_FILE, "Import GNU Triangulated Surface File");
\r
384 gnuSurfaceFile = new File( gnuSurfaceFilenameTextField.getText() );
\r
386 if ( gnuSurfaceFile.canRead() ) {
\r
387 fileChooser.setSelectedFile( gnuSurfaceFile );
\r
390 fileChooser.showDialog( window );
\r
391 file = fileChooser.getSelectedFile();
\r
393 if ( file == null ) {
\r
397 gnuSurfaceFilenameTextField.setText( file.getAbsolutePath() );
\r
398 preferencesWrite( preferencesFilename, widgetVector );
\r