Package bs.bs2d.io

Source Code of bs.bs2d.io.MeshReader

package bs.bs2d.io;

import bs.bs2d.fea.Edge;
import bs.bs2d.fea.Node2D;
import bs.bs2d.fea.TriMesh2D;
import java.awt.geom.Line2D;
import java.io.File;
import java.util.List;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.vecmath.Point2f;
import org.apache.commons.io.FileUtils;

/**
* Class for reading meshes from mesh files
* @author Djen
*/
public class MeshReader {
   
    public static final String WHITESPACE_DELIMITER = "\\s+";
   
    private static FileNameExtensionFilter fileFilter;
   
    public static TriMesh2D readMesh(File f) throws Exception{
        TriMesh2D mesh;
        if(f.getName().endsWith(".grd")){
            mesh = readGrdFile(f);
        } else if(f.getName().endsWith(".vol")){
            mesh = readVolFile(f);
        } else if(f.getName().endsWith(".msh")){
            mesh = readMshFile(f);
        } else {
            throw new Exception("Unknown file format!");
        }
       
        checkMesh(mesh);
       
        return mesh;
    }
   
    /**
     * Read a 2D mesh consisting of triangular (three node) elements from a
     * Gridgen style .grd file.
     * @param f file to read mesh data from
     * @return the mesh object described by the file
     */
    public static TriMesh2D readGrdFile(File f) throws Exception{
       
        TriMesh2D mesh = new TriMesh2D();
       
       
            List<String> lines;
            lines = FileUtils.readLines(f);
           
            int index = 0;
            while(lines.get(index).startsWith("#"))
                index++;

            String[] vals = lines.get(index).split(WHITESPACE_DELIMITER);
            index++;
           
            int nodes = Integer.parseInt(vals[0]);
            int elems = Integer.parseInt(vals[1]);
           
            // read nodes
            for(int i=0; i < nodes; i++){
                vals = lines.get(index+i).split(WHITESPACE_DELIMITER);
               
                int ni = Integer.parseInt(vals[0]);
                float x = Float.parseFloat(vals[1]);
                float y = Float.parseFloat(vals[2]);
               
                mesh.addNode(new Node2D(ni, x, y));
            }
            index += nodes;
           
            // read elements
            for(int i=0; i < elems; i++){
                vals = lines.get(index+i).split(WHITESPACE_DELIMITER);
               
                if(!vals[2].equals("tri"))
                    throw new Exception("Element type not supported: " + vals[2]);
               
                int ei = Integer.parseInt(vals[0]);
                int[] nodeIndex = new int[3];
                for(int j=0; j < 3; j++)
                    nodeIndex[j] = Integer.parseInt(vals[j+3]);
               
                mesh.addNewElement(ei, nodeIndex);
            }
           
            mesh.finalizeConstruction();
           
       
        return mesh;
    }
   
   
    /**
     * Read a 2D mesh consisting of triangular (three node) elements from a
     * GMesh style .msh file.
     * @param f file to read mesh data from
     * @return the mesh object described by the file
     */
    public static TriMesh2D readMshFile(File f) throws Exception{
       
        TriMesh2D mesh = new TriMesh2D();
       
       
            List<String> lines;
            lines = FileUtils.readLines(f);
           
            int index = lines.indexOf("$Nodes") + 1;
           
           
            String[] vals;
           
            // read nodes
            int nodes = Integer.parseInt(lines.get(index++));
            for(int i=0; i < nodes; i++){
                vals = lines.get(index+i).split(WHITESPACE_DELIMITER);
               
                int ni = Integer.parseInt(vals[0]);
                float x = Float.parseFloat(vals[1]);
                float y = Float.parseFloat(vals[2]);
               
                mesh.addNode(new Node2D(ni, x, y));
            }
            index += nodes;
            // done
           
           
            while(!lines.get(index).equals("$Elements"))
                index++;
            index++;
           
            // read elements
            int elems = Integer.parseInt(lines.get(index++));
            for(int i=0; i < elems; i++){
                vals = lines.get(index+i).split(WHITESPACE_DELIMITER);
               
                if(!vals[1].equals("2"))
                    continue;
               
                int ei = Integer.parseInt(vals[0]);
                int tags = Integer.parseInt(vals[2]);
                int[] nodeIndex = new int[3];
                for(int j=0; j < 3; j++)
                    nodeIndex[j] = Integer.parseInt(vals[3+tags+j]);
               
                mesh.addNewElement(ei, nodeIndex);
            }
           
            mesh.finalizeConstruction();
           
        return mesh;
    }
   
   
    /**
     * Read a 2D mesh consisting of triangular (three node) elements from a
     * Netgen style .vol file.
     * @param f file to read mesh data from
     * @return the mesh object described by the file
     */
    public static TriMesh2D readVolFile(File f) throws Exception{
        TriMesh2D mesh = new TriMesh2D();
       
       
            List<String> lines;
            lines = FileUtils.readLines(f);
           
            int iElems = -1;
            int nElems = 0;
            int iNodes = -1;
            int nNodes = 0;
            for (int i = 0; i < lines.size(); i++) {
                String line = lines.get(i);
                if(line.equals("points")){
                    nNodes = Integer.parseInt(lines.get(++i));
                    iNodes = ++i;
                }
                if(line.equals("surfaceelementsuv")){
                    nElems = Integer.parseInt(lines.get(++i));
                    iElems = ++i;
                }
            }
            String[] vals;
           
            // read nodes
            for(int i=0; i < nNodes; i++){
                vals = lines.get(iNodes + i).split(WHITESPACE_DELIMITER);
               
                float x = Float.parseFloat(vals[1]);
                float y = Float.parseFloat(vals[2]);
               
                mesh.addNode(new Node2D(i+1, x, y));
            }
           
            // read elements
            for(int i=0; i < nElems; i++){
                vals = lines.get(iElems + i).split(WHITESPACE_DELIMITER);
               
                if(!vals[5].equals("3"))
                    throw new Exception("Element type not supported: " + vals[5]);
               
                int[] nodeIndex = new int[3];
                for(int j=0; j < 3; j++)
                    nodeIndex[j] = Integer.parseInt(vals[j+6]);
               
                mesh.addNewElement(i, nodeIndex);
            }
           
            mesh.finalizeConstruction();
       
        return mesh;
    }
   
    public static void checkMesh(TriMesh2D mesh) throws Exception{
        if(mesh.getNodeCount() == 0 || mesh.getElementCount() == 0)
            throw new Exception("Empty mesh!");
       
        List<Node2D> nodes = mesh.getNodes();
        for (int i = 0; i < nodes.size(); i++) {
            // test manifold
            Node2D n = nodes.get(i);
            int d = 0;
            if(n.isOuter())
                d = 1;
           
            if(n.getEdgeCount()-n.getElementCount() > d){
                throw new Exception("Mesh is non-manifold!");
            }
           
            if(n.getElementCount() == 0){
                System.err.println("Mesh contains unused nodes");
            }
           
           
        }
       
        List<Edge> edges = mesh.getEdges();
        Line2D[] lines = new Line2D[mesh.getEdgeCount()];
        for (int i = 0; i < lines.length; i++) {
            Edge e = edges.get(i);
            Point2f p0 = e.getNode(0).getPoint2f();
            Point2f p1 = e.getNode(1).getPoint2f();
            lines[i] = new Line2D.Float(p0.x, p0.y, p1.x, p1.y);
           
            for(int j=0; j<i; j++){
                if(lines[i].intersectsLine(lines[j])){
                    if(!(lines[i].getP1().equals(lines[j].getP1()) ||
                         lines[i].getP1().equals(lines[j].getP2()) ||
                         lines[i].getP2().equals(lines[j].getP1()) ||
                         lines[i].getP2().equals(lines[j].getP2()) )){
                       
                        throw new Exception("Mesh contains intersecting edges!");
                    }
                }
            }
           
        }
    }

    /**
     * @return the fileFilter
     */
    public static FileNameExtensionFilter getFileFilter() {
        if(fileFilter == null){
            String description = "Mesh Files (*.grd, *.vol, *.msh)";
            String[] extensions = new String[]{"grd", "vol", "msh"};
            fileFilter = new FileNameExtensionFilter(description, extensions);
        }
        return fileFilter;
    }
   
}
TOP

Related Classes of bs.bs2d.io.MeshReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.