/* jCAE stand for Java Computer Aided Engineering. Features are : Small CAD modeler, Finite element mesher, Plugin architecture. Copyright (C) 2005, by EADS CRC Copyright (C) 2007,2008,2009, by EADS France This library 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 org.jcae.mesh.amibe.util; import org.jcae.mesh.amibe.ds.Mesh; import org.jcae.mesh.amibe.ds.Triangle; import org.jcae.mesh.amibe.ds.Vertex; import org.jcae.mesh.amibe.ds.MGroup3D; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.StringTokenizer; import java.util.ArrayList; import gnu.trove.map.hash.TIntObjectHashMap; import java.util.logging.Logger; /** * @author cb * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ public class UNVReader { private static final Logger logger=Logger.getLogger(UNVReader.class.getName()); public static void readMesh(Mesh mesh, String file) { TIntObjectHashMap<Vertex> nodesmap = null; TIntObjectHashMap<Triangle> facesmap = null; Triangle beamPlaceHolder = mesh.createTriangle(mesh.outerVertex, mesh.outerVertex, mesh.outerVertex); double unit = 1.0; String line = ""; boolean hasGroups = false; try { FileInputStream in = new FileInputStream(file); BufferedReader rd=new BufferedReader(new InputStreamReader(in)); while ((line=rd.readLine())!=null) { line = line.trim(); if (line.equals("-1")) { line = rd.readLine(); line = line.trim(); if (line.equals("2411") || line.equals("781")) { // read nodes nodesmap = readNodes(mesh, rd, unit); } else if (line.equals("2412")) { // read faces facesmap = readFace(rd, mesh, beamPlaceHolder, nodesmap); } else if (line.equals("164")) { // read unit unit = readUnit(rd); } else if ( (line.equals("2430")) || (line.equals("2435")) || (line.equals("2477")) || (line.equals("2467")) ) { // read groups int nrGroups = readGroup(rd, line, facesmap, beamPlaceHolder); hasGroups = nrGroups > 1; } else if (line.equals("2414")) { // read colors } else { // default group // read end of group while (!rd.readLine().trim().equals("-1")) { } } } } in.close(); } catch(Exception e) { e.printStackTrace(); } if (mesh.hasAdjacency()) { mesh.buildAdjacency(); if (hasGroups) mesh.buildGroupBoundaries(); } } private static double readUnit(BufferedReader rd) { double unit = 1.0; String line = ""; try { //retrieve the second line rd.readLine(); line = rd.readLine(); // fisrt number : the unit StringTokenizer st = new StringTokenizer(line); String unite = st.nextToken(); unite = unite.replace('D','E'); unit = Double.parseDouble(unite); while(!rd.readLine().trim().equals("-1")) { } } catch(Exception e) { e.printStackTrace(); } return unit; } private static TIntObjectHashMap<Vertex> readNodes(Mesh m, BufferedReader rd, double unit) { TIntObjectHashMap<Vertex> nodesmap = new TIntObjectHashMap<Vertex>(); logger.fine("Reading nodes"); nodesmap.clear(); double x,y,z; String line = ""; try { while(!(line=rd.readLine().trim()).equals("-1")) { //First number : the node's id StringTokenizer st = new StringTokenizer(line); int index = Integer.parseInt(st.nextToken()); line = rd.readLine(); //line contains coord x,y,z st = new StringTokenizer(line); String x1 = st.nextToken(); String y1 = st.nextToken(); String z1; try { z1 = st.nextToken(); } catch (java.util.NoSuchElementException ex) { z1="0.0"; } x1 = x1.replace('D','E'); y1 = y1.replace('D','E'); z1 = z1.replace('D','E'); x = Double.parseDouble(x1) /unit; y = Double.parseDouble(y1) /unit; z = Double.parseDouble(z1) /unit; Vertex n = m.createVertex(x,y,z); n.setLabel(index); nodesmap.put(index, n); if (m.hasNodes()) m.add(n); } } catch(Exception e) { e.printStackTrace(); } logger.fine("Found "+nodesmap.size()+" nodes"); return nodesmap; } private static TIntObjectHashMap<Triangle> readFace(BufferedReader rd, Mesh mesh, Triangle beamPlaceHolder, TIntObjectHashMap<Vertex> nodesmap) { logger.fine("Reading triangles"); TIntObjectHashMap<Triangle> facesmap = new TIntObjectHashMap<Triangle>(); String line = ""; boolean quad = false; int beams = 0; try { while (!(line=rd.readLine().trim()).equals("-1")) { // first line: type of object StringTokenizer st = new StringTokenizer(line); String index = st.nextToken(); String type = st.nextToken(); int ind = Integer.valueOf(index).intValue(); if (type.equals("41") || type.equals("51") || type.equals("61") || type.equals("74") || type.equals("91") || type.equals("92")) { line=rd.readLine(); // triangle st = new StringTokenizer(line); boolean parabolic = type.equals("92"); int p1 = Integer.valueOf(st.nextToken()).intValue(); if (parabolic) st.nextToken(); int p2 = Integer.valueOf(st.nextToken()).intValue(); if (parabolic) st.nextToken(); int p3 = Integer.valueOf(st.nextToken()).intValue(); if (parabolic) st.nextToken(); Vertex n1 = nodesmap.get(p1); assert n1 != null : p1; Vertex n2 = nodesmap.get(p2); assert n2 != null : p2; Vertex n3 = nodesmap.get(p3); assert n3 != null : p3; Triangle f = mesh.createTriangle(n1, n2, n3); mesh.add(f); // fill the map of faces facesmap.put(ind, f); } else if (type.equals("44") || type.equals("54") || type.equals("64") || type.equals("71") || type.equals("94")) { quad = true; line=rd.readLine(); // quadrangle st = new StringTokenizer(line); int p1 = Integer.valueOf(st.nextToken()).intValue(); int p2 = Integer.valueOf(st.nextToken()).intValue(); int p3 = Integer.valueOf(st.nextToken()).intValue(); int p4 = Integer.valueOf(st.nextToken()).intValue(); Vertex n1 = nodesmap.get(p1); assert n1 != null : p1; Vertex n2 = nodesmap.get(p2); assert n2 != null : p2; Vertex n3 = nodesmap.get(p3); assert n3 != null : p3; Vertex n4 = nodesmap.get(p4); assert n4 != null : p4; Triangle f = mesh.createTriangle(n1, n2, n3); mesh.add(f); facesmap.put(ind, f); f = mesh.createTriangle(n1, n3, n4); mesh.add(f); facesmap.put(-ind, f); } else if (type.equals("11") || type.equals("21")) { beams++; rd.readLine(); rd.readLine(); facesmap.put(ind, beamPlaceHolder); } else throw new RuntimeException("Type "+type+" unknown"); } } catch(Exception e) { e.printStackTrace(); } logger.fine("Found "+facesmap.size()+" triangles"); if (quad) logger.severe("Quadrangles have been detected and converted into triangles. If errors occur, convert this UNV file to only use triangles!"); if (beams > 0) { if (facesmap.size() == beams) logger.severe("Beams have been found but are discarded, and this mesh does not contain any triangle!"); else logger.severe("Beams have been found but are discarded, only triangles are read."); } return facesmap; } private static int readGroup(BufferedReader rd, String type, TIntObjectHashMap<Triangle> facesmap, Triangle beamPlaceHolder) { logger.fine("Reading groups"); String line = ""; int groupIdx = 0; try { line = rd.readLine(); while(!line.trim().equals("-1")) { // read the number of elements to read in the last number of the line StringTokenizer st = new StringTokenizer(line); String snb = ""; // Block number st.nextToken(); while(st.hasMoreTokens()) { snb = st.nextToken(); } // Number of elements int nbelem = Integer.valueOf(snb).intValue(); // Read group name String title = rd.readLine().trim(); ArrayList<Triangle> facelist = new ArrayList<Triangle>(); // read the group while ((line= rd.readLine().trim()).startsWith("8")) { st = new StringTokenizer(line); // read one element over two, the first one doesnt matter while(st.hasMoreTokens()) { st.nextToken(); String index = st.nextToken(); int ind = Integer.valueOf(index).intValue(); if (ind != 0) { Triangle f = facesmap.get(ind); if (f == beamPlaceHolder) { // Do nothing } else if (f != null) { facelist.add(f); f.setGroupId(groupIdx); } else logger.severe("In group "+groupIdx+", element number "+ind+" does not exist"); } nbelem--; if (type.equals("2430") || type.equals("2435") || type.equals("2477") || type.equals("2467")) { st.nextToken(); st.nextToken(); } } if (nbelem <= 0) { line = rd.readLine(); break; } } new MGroup3D(groupIdx, title, facelist); groupIdx++; } } catch(Exception e) { e.printStackTrace(); } return groupIdx; } }