/* jCAE stand for Java Computer Aided Engineering. Features are : Small CAD modeler, Finite element mesher, Plugin architecture. Copyright (C) 2003,2004,2005, by EADS CRC Copyright (C) 2007,2008, 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.xmldata; import java.io.File; import java.util.HashMap; import java.util.HashSet; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.jcae.mesh.amibe.ds.MEdge1D; import org.jcae.mesh.amibe.ds.MMesh1D; import org.jcae.mesh.amibe.ds.MNode1D; import org.jcae.mesh.amibe.ds.SubMesh1D; import org.jcae.mesh.cad.CADEdge; import org.jcae.mesh.cad.CADVertex; import org.jcae.mesh.cad.CADShape; import org.jcae.mesh.cad.CADShapeFactory; import org.jcae.mesh.cad.CADShapeEnum; import org.jcae.mesh.cad.CADExplorer; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.util.logging.Logger; public class MMesh1DReader { private static final Logger logger=Logger.getLogger(MMesh1DReader.class.getName()); /** Return the first child element of with the given tag name */ private static Node getChild(Node e, String tagName) { Node n=e.getFirstChild(); while(n!=null) { if(n instanceof Element) { if(tagName.equals(n.getNodeName())) { return n; } } n=n.getNextSibling(); } return null; } private static int getReferenceNumber(Node nodeElement) { Node ref=getChild(nodeElement, "references"); Node num=getChild(ref, "number"); return Integer.parseInt(num.getFirstChild().getNodeValue()); } /** * Write the current object to a XML file and binary files. The XML file * have links to the binary files. * @param xmlDir name of the XML file */ public static MMesh1D readObject(String xmlDir) { MMesh1D m1d = null; int i; File xmlFile1d = new File(xmlDir, JCAEXMLData.xml1dFilename); logger.fine("begin reading "+xmlFile1d); XPath xpath = XPathFactory.newInstance().newXPath(); HashMap<CADVertex, MNode1D> map1DToMaster = new HashMap<CADVertex, MNode1D>(); try { Document document = XMLHelper.parseXML(xmlFile1d); String formatVersion = xpath.evaluate("/jcae/@version", document); if (formatVersion != null && formatVersion.length() > 0) throw new RuntimeException("File "+xmlFile1d+" has been written by a newer version of jCAE and cannot be re-read"); String brepFile = xpath.evaluate("/jcae/mesh/shape/file/@location", document); if(!new File(brepFile).isAbsolute()) brepFile = xmlDir+File.separator+brepFile; m1d = new MMesh1D(brepFile); CADShape shape = m1d.getGeometry(); String nodesFile = xpath.evaluate( "/jcae/mesh/submesh/nodes/file/@location", document); if (nodesFile.charAt(0) != File.separatorChar) nodesFile = xmlDir+File.separator+nodesFile; PrimitiveFileReaderFactory pfrf = new PrimitiveFileReaderFactory(); DoubleFileReader dfrN = pfrf.getDoubleReader(new File(nodesFile)); String refFile = xpath.evaluate( "/jcae/mesh/submesh/nodes/references/file/@location", document); if (refFile.charAt(0) != File.separatorChar) refFile = xmlDir+File.separator+refFile; IntFileReader ifrR = pfrf.getIntReader(new File(refFile)); String edgesFile = xpath.evaluate( "/jcae/mesh/submesh/beams/file/@location", document); if (edgesFile.charAt(0) != File.separatorChar) edgesFile = xmlDir+File.separator+edgesFile; IntFileReader ifrE = pfrf.getIntReader(new File(edgesFile)); NodeList submeshList = (NodeList) xpath.evaluate( "/jcae/mesh/submesh", document.getDocumentElement(), XPathConstants.NODESET); int iEdge = 0; // References are counted from 1; 0 means an inner // vertex. Offset is thus set to 1. int offset = 1; HashSet<CADEdge> setSeenEdges = new HashSet<CADEdge>(); CADExplorer expE = CADShapeFactory.getFactory().newExplorer(); for (expE.init(shape, CADShapeEnum.EDGE); expE.more(); expE.next()) { CADEdge E = (CADEdge) expE.current(); SubMesh1D submesh = m1d.getSubMesh1DFromMap(E); if (null == submesh || setSeenEdges.contains(E)) continue; setSeenEdges.add(E); iEdge++; submesh.getNodes().clear(); submesh.getEdges().clear(); Node submeshElement = submeshList.item(iEdge-1); Node submeshNodes = getChild(submeshElement, "nodes"); int numberOfReferences = getReferenceNumber(submeshNodes); int [] refs = new int[2*numberOfReferences]; ifrR.get(refs); for (i=0; i < numberOfReferences; i++) refs[2*i] -= offset; int numberOfNodes = Integer.parseInt( getChild(submeshNodes, "number").getFirstChild().getNodeValue()); MNode1D [] nodelist = new MNode1D[numberOfNodes]; int iref = 0; for (i=0; i < numberOfNodes; i++) { if (iref < 2*numberOfReferences && refs[iref] == i) { CADVertex V = m1d.getGeometricalVertex(refs[iref+1]); nodelist[i] = new MNode1D(dfrN.get(), V); MNode1D master = map1DToMaster.get(V); if (null == master) map1DToMaster.put(V, nodelist[i]); else nodelist[i].setMaster(master); iref += 2; } else nodelist[i] = new MNode1D(dfrN.get(), null); submesh.getNodes().add(nodelist[i]); } Node submeshEdges = getChild(submeshElement, "beams"); int numberOfEdges = Integer.parseInt( getChild(submeshEdges, "number").getFirstChild().getNodeValue()); for (i=0; i < numberOfEdges; i++) { MNode1D pt1 = nodelist[ifrE.get() - offset]; MNode1D pt2 = nodelist[ifrE.get() - offset]; MEdge1D e = new MEdge1D(pt1, pt2); submesh.getEdges().add(e); } offset += numberOfNodes; } ifrE.close(); dfrN.close(); ifrR.close(); } catch(Exception ex) { ex.printStackTrace(); throw new RuntimeException(ex); } logger.fine("end reading "+JCAEXMLData.xml1dFilename); return m1d; } }