/*
* 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 2007-2012 by EADS France
*/
package org.jcae.mesh.xmldata;
import java.util.logging.Level;
import org.jcae.mesh.xmldata.AmibeReader.Group;
import org.jcae.mesh.xmldata.AmibeReader.SubMesh;
import org.jcae.mesh.xmldata.MeshExporter.UNV.Unit;
import java.io.File;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.logging.Logger;
import org.xml.sax.SAXException;
/**
* Convert an Amibe mesh to a UNV mesh.
* The convertion is out-of-core and can handle large mesh.
* @see MeshExporter.UNV
* @author Jerome Robert
*/
public class Amibe2UNV
{
private final static String CR=System.getProperty("line.separator");
private final static NumberFormat FORMAT_I10=new MeshExporter.FormatI10();
private static final Logger logger=Logger.getLogger(Amibe2UNV.class.getName());
/**
* A main method for debugging
* @param args
*/
public static void main(String[] args)
{
try
{
PrintStream p=new PrintStream(new BufferedOutputStream(new FileOutputStream(
"/tmp/blub2.unv")));
new MeshExporter.UNV("/home/jerome/OCCShapeGal/amibe1.dir/").write(p);
//new Amibe2UNV(new File("/home/jerome/jCAE-cvs-head/FLIGHT0.01")).write(p);
p.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
private final String directory;
private final MeshExporter.UNV unvWriter;
private double scale = 1.0;
private int elementary = 1;
/**
* This is the number written just after the type of elements.
* The default is 1. gmsh use this number to set the id of the create GFace
* when using the Merge command.
*/
public void setElementary(int elementary) {
this.elementary = elementary;
}
/**
* @param directory The directory which contain 3d files
*/
public Amibe2UNV(String directory)
{
this.directory=directory;
this.unvWriter = new MeshExporter.UNV(directory);
}
public Amibe2UNV(File directory)
{
this(directory.getPath());
}
public void setUnit(Unit unit)
{
unvWriter.setUnit(unit);
}
public void setScale(double scale)
{
this.scale = scale;
}
public void write(String fileName) throws IOException, SAXException
{
PrintStream out = new PrintStream(fileName);
write(out);
out.close();
}
public void write(PrintStream out) throws SAXException, IOException
{
AmibeReader.Dim3 ar = new AmibeReader.Dim3(directory);
SubMesh sm = ar.getSubmeshes().get(0);
unvWriter.writeInit(out);
writeNodes(out);
out.println(" -1"+CR+" 2412");
int count = writeTriangles(out, sm);
writeBeams(out, sm, count);
out.println(" -1");
writeGroups(out, sm, count);
}
/**
* Match Amibe groups name to UNV group.
* Return an array of groups so an amibe group can be in more than one
* UNV group.
*/
protected String[] formatGroupName(String name)
{
return new String[]{name};
}
private Map<String, Collection<Group>> indexUNVGroups(Collection<Group> groups)
{
Map<String, Collection<Group>> toReturn = new TreeMap<String, Collection<Group>>();
for(Group g:groups)
{
for(String unvG:formatGroupName(g.getName()))
{
Collection<Group> l = toReturn.get(unvG);
if(l == null)
{
l = new ArrayList<Group>();
toReturn.put(unvG, l);
}
l.add(g);
}
}
return toReturn;
}
private int getNumberOfItems(Collection<Group> l)
{
int r = 0;
for(Group g:l)
r += g.getNumberOfBeams()+g.getNumberOfNodes()+g.getNumberOfTrias();
return r;
}
/**
* @param out
* @param count id of the first beam
* @throws IOException
*/
private void writeGroups(PrintStream out, AmibeReader.SubMesh subMesh, int count)
throws SAXException, IOException
{
out.println(" -1"+CR+" 2435");
int i = 0;
for(Entry<String, Collection<Group>> e:indexUNVGroups(subMesh.getGroups()).entrySet())
{
out.println(FORMAT_I10.format(i+1)+
" 0 0 0 0 0 0"+
FORMAT_I10.format(getNumberOfItems(e.getValue())));
out.println(e.getKey());
int countg=0;
for(Group g:e.getValue())
{
for(int id:g.readTria3Ids())
{
out.print(" 8"
+FORMAT_I10.format(id+1)
+" 0 0");
countg++;
if ((countg % 2) == 0)
out.println();
}
}
for(Group g:e.getValue())
{
for(int id:g.readBeamsIds())
{
out.print(" 8"
+FORMAT_I10.format(id+count)
+" 0 0");
countg++;
if ((countg % 2) == 0)
out.println();
}
}
for(Group g:e.getValue())
{
for(int id:g.readNodesIds())
{
out.print(" 7"
+FORMAT_I10.format(id+1)
+" 0 0");
countg++;
if ((countg % 2) == 0)
out.println();
}
}
if ((countg % 2) !=0 )
out.println();
i++;
}
out.println(" -1");
}
private void writeNodes(PrintStream out) throws IOException
{
DoubleFileReader f=unvWriter.getSubMesh().getNodes();
int count = 1;
out.println(" -1"+CR+" 2411");
double[] buffer = new double[3];
int nbNodes = (int) (f.size() / 3);
for(int i = 0; i < nbNodes; i++)
{
f.get(buffer);
MeshExporter.UNV.writeSingleNode(out, count,
buffer[0]*scale, buffer[1]*scale, buffer[2]*scale);
count ++;
}
out.println(" -1");
f.close();
logger.info("Total number of nodes: "+count);
}
/**
* @param out
* @throws IOException
*/
private int writeTriangles(PrintStream out, AmibeReader.SubMesh subMesh) throws IOException
{
int count = 1;
if(subMesh.getNumberOfTrias() > 0)
{
IntFileReader trias = subMesh.getTriangles();
long nb = trias.size() / 3;
for(int i = 0; i<nb; i++)
{
int n1 = trias.get();
int n2 = trias.get();
int n3 = trias.get();
if(n1 >= 0)
MeshExporter.UNV.writeSingleTriangle(out, count,
n1+1, n2+1, n3+1, elementary);
count ++;
}
}
logger.log(Level.INFO, "Total number of triangles: {0}", count-1);
return count;
}
private void writeBeams(PrintStream out, AmibeReader.SubMesh subMesh, int count) throws IOException
{
if(subMesh.getNumberOfBeams() > 0)
{
IntFileReader beams = subMesh.getBeams();
long nb = beams.size() / 2;
for(int i = 0; i < nb; i++)
{
out.println(FORMAT_I10.format(count) +
" 21 2 1 5 2");
out.println(" 0 1 1");
out.println(FORMAT_I10.format(beams.get()+1) + FORMAT_I10.format(beams.get()+1));
count ++;
}
}
}
}