/*
* 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 2010, by EADS France
*/
package org.jcae.mesh.xmldata;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.xpath.XPathExpressionException;
import org.jcae.mesh.xmldata.AmibeWriter.Dim3;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* Convert a GPure mesh to an Amibe mesh.
*/
public class GPure2Amibe extends XMLReader {
private final String outputDir;
private Dim3 out;
private int nodeCounter;
private final Set<String> groupNames = new HashSet<String>();
public GPure2Amibe(String outputDir) {
this.outputDir = outputDir;
}
@Override
protected void read(Document dom) throws SAXException,
XPathExpressionException,
IOException {
out = new AmibeWriter.Dim3(outputDir);
out.setFixNoGroup(true);
Element triaElement = null;
ArrayList<Element> edgeElements = new ArrayList<Element>();
ArrayList<Element> partitionElements = new ArrayList<Element>();
for(Element e:getElements(dom.getDocumentElement(), "rdf:Description"))
{
Element typeElement = getElement(e, "GPure:type");
String type = typeElement == null ? null : typeElement.getTextContent().trim();
if("Data".equals(type))
partitionElements.add(e);
else if("Tesselation".equals(type))
{
if(getElement(e, "GPure:positions") == null)
continue;
if(getElement(e, "GPure:faces") == null)
edgeElements.add(e);
else
{
if(triaElement != null)
throw new IllegalStateException("Cannot convert a file"+
"containing more than one triangulated part");
triaElement = e;
}
}
}
if(triaElement != null)
{
Element positions = getElement(triaElement, "GPure:positions");
addNodes(positions.getTextContent());
//free some memory
positions.setTextContent("");
Element faces = getElement(triaElement, "GPure:faces");
addTriangles(faces.getTextContent());
//free some memory
GPure:faces.setTextContent("");
}
writeGroups(partitionElements);
int beamOffset = 0;
for(Element e:edgeElements)
{
int nodeOffset = nodeCounter;
Element positions = getElement(e, "GPure:positions");
addNodes(positions.getTextContent());
Element edges = getElement(e, "GPure:edges");
beamOffset += addBeams(edges.getTextContent(), nodeOffset, beamOffset);
}
out.finish();
}
private void writeGroups(List<Element> partitionElements) throws IOException
{
// sort group alphabetically
TreeMap<String, Element> sortedPartitions = new TreeMap<String, Element>();
for(Element e:partitionElements)
{
Element dataGroup = getElement(e, "GPure:dataGroup");
if(dataGroup != null && "partitionDataSet".equals(dataGroup.getTextContent()))
{
String name = getFreeName(getElement(e, "GPure:name").getTextContent());
sortedPartitions.put(name, e);
}
}
for(Entry<String, Element> e:sortedPartitions.entrySet())
{
out.nextGroup(e.getKey());
addToGroup(getElement(e.getValue(), "GPure:faces").getTextContent());
}
}
private String getFreeName(String root)
{
String toReturn;
if(groupNames.contains(root))
{
int i = 1;
String name;
do
{
name = root + i;
i++;
}
while(groupNames.contains(name));
toReturn = name;
}
else
toReturn = root;
groupNames.add(toReturn);
return toReturn;
}
@Override
protected String getXSD() {
return null;
}
public static void main(final String[] args) {
try {
new GPure2Amibe("/tmp/testamibe").read(new File("/tmp/zebra7116.tmp/zebra-out.gpure"));
} catch (SAXException ex) {
Logger.getLogger(GPure2Amibe.class.getName()).log(Level.SEVERE, null,
ex);
} catch (IOException ex) {
Logger.getLogger(GPure2Amibe.class.getName()).log(Level.SEVERE, null,
ex);
}
}
private void addNodes(String textContent) throws IOException {
StringTokenizer cordinatesAll = new StringTokenizer(textContent, ", \n");
while (cordinatesAll.hasMoreTokens()) {
out.addNode(Double.parseDouble(cordinatesAll.nextToken()),
Double.parseDouble(cordinatesAll.nextToken()),
Double.parseDouble(cordinatesAll.nextToken()));
nodeCounter ++;
}
}
private void addTriangles(String textContent) throws IOException {
StringTokenizer cordinatesAll = new StringTokenizer(textContent, " \n");
while (cordinatesAll.hasMoreTokens()) {
out.addTriangle(Integer.parseInt(cordinatesAll.nextToken()),
Integer.parseInt(cordinatesAll.nextToken()),
Integer.parseInt(cordinatesAll.nextToken()));
}
}
private void addToGroup(String textContent) throws IOException {
StringTokenizer cordinatesAll = new StringTokenizer(textContent, " \n");
while (cordinatesAll.hasMoreTokens()) {
out.addTriaToGroup(Integer.parseInt(cordinatesAll.nextToken()));
}
}
private int addBeams(String textContent, int nodeOffset, int beamOffset) throws IOException {
StringTokenizer cordinatesAll = new StringTokenizer(textContent, " \n");
int id = 0;
out.nextGroup(""+beamOffset);
while (cordinatesAll.hasMoreTokens()) {
out.addBeam(
nodeOffset + Integer.parseInt(cordinatesAll.nextToken()),
nodeOffset + Integer.parseInt(cordinatesAll.nextToken()));
out.addBeamToGroup(beamOffset+id);
id ++;
}
return id;
}
}