/*
* Project Info: http://jcae.sourceforge.net
*
* 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 2011, by EADS France
*/
package org.jcae.mesh.xmldata;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Pierre Benjamin, Jerome Robert
*/
public class Capitole2Amibe
{
/**
* Map a capitol element ID with Amibe element ID.
* This is required because capitol file mix beams and trias while amibe
* separate them
* This is done in a temporary file to save memory
*/
private static class IDMapping
{
/**
* Element type in the temporary file used to separate beams from trias
* in groups.
*/
public static int TRIAS = 0, BEAMS = 1;
private FileChannel channel;
private File file;
private ByteBuffer buffer = ByteBuffer.allocate(8);
public IDMapping() throws IOException
{
file = File.createTempFile("amibe", ".bin");
file.deleteOnExit();
channel = new RandomAccessFile(file, "rw").getChannel();
}
public void close() throws IOException
{
channel.close();
file.delete();
}
public void add(int amibeID, int type) throws IOException
{
buffer.rewind();
buffer.putInt(amibeID);
buffer.putInt(type);
buffer.rewind();
channel.write(buffer);
}
public void seek(int id) throws IOException
{
buffer.rewind();
channel.read(buffer, 8*id);
}
public int getID()
{
return buffer.getInt(0);
}
public int getType()
{
return buffer.getInt(4);
}
}
private static final Logger LOGGER=Logger.getLogger(Capitole2Amibe.class.getName());
private int nbPoints;
private int nbTria ;
private int nbBeam ;
private IDMapping idMapping;
public final void importMesh(String input, String output) throws IOException
{
importMesh(new File(input), output);
}
public final void importMesh(File input, String output) throws IOException
{
BufferedReader br=new BufferedReader(new FileReader(input));
importMesh(br, output);
br.close();
}
public final void importMesh(BufferedReader in, String outputDir) throws IOException
{
AmibeWriter.Dim3 out = new AmibeWriter.Dim3(outputDir);
out.setFixNoGroup(true);
importMesh(in, out);
out.finish();
}
private void importMesh(BufferedReader in, AmibeWriter.Dim3 out) throws IOException
{
idMapping = new IDMapping();
double unit = 1.0;
String line;
while ((line = in.readLine()) != null) {
if (line.trim().equals("<POINT>")) {
// read nodes
convertNodes(in, nbPoints, unit, out);
} else if (line.trim().equals("<TRIANGLE>")) {
// read faces
convertFaces(in, "TRIANGLE", nbTria, out);
} else if (line.trim().equals("<WIRES>")) {
// read faces
convertFaces(in, "WIRE", nbBeam, out);
} else if (line.trim().equals("<DIMENSION>")) {
// read unit
readDimension(in);
LOGGER.log(Level.INFO, "NbPoints = {0}", nbPoints);
}
}
idMapping.close();
}
private void readDimension(BufferedReader rd) throws IOException
{
String line = "";
StringTokenizer st;
//first line = nbPoints + comment
line = rd.readLine();
st = new StringTokenizer(line);
this.nbPoints = Integer.parseInt(st.nextToken());
//second line = nbTriangles + comment
line = rd.readLine();
st = new StringTokenizer(line);
this.nbTria = Integer.parseInt(st.nextToken());
//third line = nbEdges + comment: inutile
line = rd.readLine();
//fourth line = nbPoutres + comment
line = rd.readLine();
st = new StringTokenizer(line);
this.nbBeam = Integer.parseInt(st.nextToken());
}
private void convertNodes(BufferedReader rd, int nbNodes, double unit, AmibeWriter.Dim3 out)
throws IOException
{
double x,y,z;
String line = "";
// Ligne Commentaire
//Index T IdType X Y Z Status Domain
line = rd.readLine();
for (int i = 0; i < nbNodes; i++)
{
line = rd.readLine();
//line contains coord x,y,z
StringTokenizer st = new StringTokenizer(line);
st.nextToken();st.nextToken(); st.nextToken();
String x1 = st.nextToken();
String y1 = st.nextToken();
String z1 = st.nextToken();
x = Double.parseDouble(x1)/unit;
y = Double.parseDouble(y1)/unit;
z = Double.parseDouble(z1)/unit;
out.addNode(x, y, z);
}
}
private void convertFaces(BufferedReader rd, String type, int number,
AmibeWriter.Dim3 out) throws IOException {
LOGGER.fine("Reading triangles");
String line = "";
int nbTrias = 0;
int nbBeams = 0;
//Index Id Pt1 Pt2 Pt3 Status Meth RadTyp Domains Object
line = rd.readLine();
for (int i = 0; i < number; i++) {
line = rd.readLine();
StringTokenizer st = new StringTokenizer(line);
st.nextToken(); // face index
if ("TRIANGLE".equals(type)) {
st = new StringTokenizer(line);
st.nextToken();
int p1, p2, p3;
p1 = Integer.parseInt(st.nextToken());
p2 = Integer.parseInt(st.nextToken());
p3 = Integer.parseInt(st.nextToken());
out.addTriangle(p1 - 1, p2 - 1, p3 - 1);
idMapping.add(nbTrias, IDMapping.TRIAS);
nbTrias++;
} else if ("WIRE".equals(type)) {
st = new StringTokenizer(line);
st.nextToken();
int p1, p2, p3;
p1 = Integer.parseInt(st.nextToken());
p2 = Integer.parseInt(st.nextToken());
out.addBeam(p1 - 1, p2 - 1);
idMapping.add(nbBeams, IDMapping.BEAMS);
nbBeams++;
}
}
}
public static void main(String[] args)
{
try
{
Capitole2Amibe u=new Capitole2Amibe();
String capiFile = "/tmp/pouet.geom";
String amibeDir = "/tmp/pouet";
if (args.length > 0)
capiFile = args[0];
if (args.length > 1)
amibeDir = args[1];
u.importMesh(capiFile, amibeDir);
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, null, ex);
}
}
}