Android Open Source - ScalAR Obj Parser






From Project

Back to project page ScalAR.

License

The source code is released under:

GNU General Public License

If you think the Android project ScalAR listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
  Copyright (C) 2010  Tobias Domhan/*from w ww  . j a  va  2s  .  c  o  m*/

    This file is part of AndObjViewer.

    AndObjViewer is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    AndObjViewer 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with AndObjViewer.  If not, see <http://www.gnu.org/licenses/>.
 
 */
package edu.dhbw.andobjviewer.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;
import edu.dhbw.andobjviewer.models.Group;
import edu.dhbw.andobjviewer.models.Model;
import edu.dhbw.andobjviewer.util.BaseFileUtil;

/**
 * Simple obj parser.
 * Does not support the full obj specification.
 * It supports:
 *   - vertices
 *  - vertice normals
 *  - texture coordinates
 *  - basic materials
 *  - faces(faces may not omit the face normal)
 *  - limited texture support, through the map_Kd statement (no options allowed, only image files allowed)
 * @author tobi
 *
 */
public class ObjParser {
  private final int VERTEX_DIMENSIONS = 3;
  private final int TEXTURE_COORD_DIMENSIONS = 2;
  
  private BaseFileUtil fileUtil;
  
  public ObjParser(BaseFileUtil fileUtil) {
    this.fileUtil = fileUtil;
  }
  
  /**
   * parses an wavefront obj model file
   * @param modelName name of the model
   * @param is stream of the file to parse
   * @return the parsed model
   * @throws IOException
   * @throws ParseException
   */
  public Model parse(String modelName, BufferedReader is) throws IOException, ParseException {
    //global vertices/normals
    ArrayList<float[]> vertices = new ArrayList<float[]>(1000);
    ArrayList<float[]> normals = new ArrayList<float[]>(1000);
    ArrayList<float[]> texcoords = new ArrayList<float[]>();
    
    
    Model model = new Model();
    Group curGroup = new Group();
    MtlParser mtlParser = new MtlParser(model,fileUtil);
    SimpleTokenizer spaceTokenizer = new SimpleTokenizer();
    SimpleTokenizer slashTokenizer = new SimpleTokenizer();
    slashTokenizer.setDelimiter("/");
    
    String line;
    int lineNum = 1;
    for (line = is.readLine(); 
    line != null; 
    line = is.readLine(), lineNum++)
    {
      if (line.length() > 0) {
        if (line.startsWith("#")) {
          //ignore comments
        } else if (line.startsWith("v ")) {
          //add new vertex to vector
          String endOfLine = line.substring(2);
          spaceTokenizer.setStr(endOfLine);
          vertices.add(new float[]{
              Float.parseFloat(spaceTokenizer.next()),
              Float.parseFloat(spaceTokenizer.next()),
              Float.parseFloat(spaceTokenizer.next())});
        }
        else if (line.startsWith("vt ")) {
          //add new texture vertex to vector
          String endOfLine = line.substring(3);
          spaceTokenizer.setStr(endOfLine);
          texcoords.add(new float[]{
              Float.parseFloat(spaceTokenizer.next()),
              Float.parseFloat(spaceTokenizer.next())});
        }
        else if (line.startsWith("f ")) {
          //add face to group
          String endOfLine = line.substring(2);
          spaceTokenizer.setStr(endOfLine);
          int faces = spaceTokenizer.delimOccurCount()+1;
          if(faces != 3) {
            throw new ParseException(modelName,
                lineNum, "only triangle faces are supported");
          }
          for (int i = 0; i < 3; i++) {//only triangles supported
            String face = spaceTokenizer.next();
            slashTokenizer.setStr(face);
            int vertexCount = slashTokenizer.delimOccurCount()+1;
            int vertexID=0;
            int textureID=-1;
            int normalID=0;
            if(vertexCount == 2) {
              //vertex reference
              vertexID = Integer.parseInt(slashTokenizer.next())-1;
              //normal reference
              normalID = Integer.parseInt(slashTokenizer.next())-1;
              throw new ParseException(modelName,
                  lineNum,
                  "vertex normal needed.");
            } else if(vertexCount == 3) {
              //vertex reference
              vertexID = Integer.parseInt(slashTokenizer.next())-1;
              String texCoord = slashTokenizer.next();
              if(!texCoord.equals("")) {
                //might be omitted
                //texture coord reference
                textureID = Integer.parseInt(texCoord)-1;
              }
              //normal reference
              normalID = Integer.parseInt(slashTokenizer.next())-1;
            } else {
              throw new ParseException(modelName,
                  lineNum,
                  "a faces needs reference a vertex, a normal vertex and optionally a texture coordinate per vertex.");
            }
            float[] vec;
            try {
              vec = vertices.get(vertexID);
            } catch (IndexOutOfBoundsException ex) {
              throw new ParseException(modelName,
                  lineNum,
                  "non existing vertex referenced.");
            }
            if(vec==null)
              throw new ParseException(modelName,
                  lineNum,
                  "non existing vertex referenced.");
            for (int j = 0; j < VERTEX_DIMENSIONS; j++)
              curGroup.groupVertices.add(vec[j]);
            if(textureID != -1) {
              //in case there is a texture on the face
              try {
                vec = texcoords.get(textureID);
              } catch (IndexOutOfBoundsException ex) {
                throw new ParseException(modelName,
                    lineNum,
                    "non existing texture coord referenced.");
              }
              if(vec==null)
                throw new ParseException(modelName,
                    lineNum,
                    "non existing texture coordinate referenced.");
              for (int j = 0; j < TEXTURE_COORD_DIMENSIONS; j++)
                curGroup.groupTexcoords.add(vec[j]);
            }
            try {
              vec = normals.get(normalID);
            } catch (IndexOutOfBoundsException ex) {
              throw new ParseException(modelName,
                  lineNum,
                  "non existing normal vertex referenced.");
            }
            if(vec==null)
              throw new ParseException(modelName,
                  lineNum,
                  "non existing normal vertex referenced.");
            for (int j = 0; j < VERTEX_DIMENSIONS; j++)
              curGroup.groupNormals.add(vec[j]);
          }
        }
        else if (line.startsWith("vn ")) {
          //add new vertex normal to vector
          String endOfLine = line.substring(3);
          spaceTokenizer.setStr(endOfLine);
          normals.add(new float[]{
              Float.parseFloat(spaceTokenizer.next()),
              Float.parseFloat(spaceTokenizer.next()),
              Float.parseFloat(spaceTokenizer.next())});
        } else if (line.startsWith("mtllib ")) {
          //parse material file
          //get  ID of the mtl file
          String filename = line.substring(7);
          String[] files = Util.splitBySpace(filename);
          for (int i = 0; i < files.length; i++) {
            BufferedReader mtlFile = fileUtil.getReaderFromName(files[i]);
            if(mtlFile != null)
              mtlParser.parse(model, mtlFile);
          }          
        } else if(line.startsWith("usemtl ")) {
          //material changed -> new group
          if(curGroup.groupVertices.size()>0) {
            model.addGroup(curGroup);
            curGroup = new Group();
          }
          //the rest of the line contains the name of the new material
          curGroup.setMaterialName(line.substring(7));
        } else if(line.startsWith("g ")) {
          //new group definition
          if(curGroup.groupVertices.size()>0) {
            model.addGroup(curGroup);
            curGroup = new Group();
            //group name will be ignored so far...is there any use?
          }
        }
      }
    }
    if(curGroup.groupVertices.size()>0) {
      model.addGroup(curGroup);
    }
    Iterator<Group> groupIt = model.getGroups().iterator();
    while (groupIt.hasNext()) {
      Group group = (Group) groupIt.next();
      group.setMaterial(model.getMaterial(group.getMaterialName()));
    }
    return model;
  }
}




Java Source Code List

com.skylion.speech.GoogleTranslate.java
com.skylion.speech.Narrator.java
com.skylion.speech.Synthesiser.java
edu.dhbw.andar.ARObject.java
edu.dhbw.andar.ARToolkit.java
edu.dhbw.andar.AndARActivity.java
edu.dhbw.andar.AndARRenderer.java
edu.dhbw.andar.CameraHolder.java
edu.dhbw.andar.CameraParameters.java
edu.dhbw.andar.CameraPreviewHandler.java
edu.dhbw.andar.CameraStatus.java
edu.dhbw.andar.Config.java
edu.dhbw.andar.GenericFunctions.java
edu.dhbw.andar.exceptions.AndARException.java
edu.dhbw.andar.exceptions.AndARRuntimeException.java
edu.dhbw.andar.interfaces.MarkerVisibilityListener.java
edu.dhbw.andar.interfaces.OpenGLRenderer.java
edu.dhbw.andar.interfaces.PreviewFrameSink.java
edu.dhbw.andar.pub.CustomActivity.java
edu.dhbw.andar.pub.CustomObject.java
edu.dhbw.andar.pub.CustomRenderer.java
edu.dhbw.andar.pub.SimpleBox.java
edu.dhbw.andar.util.GraphicsUtil.java
edu.dhbw.andar.util.IO.java
edu.dhbw.andobjviewer.AugmentedModelViewerActivity.java
edu.dhbw.andobjviewer.CheckFileManagerActivity.java
edu.dhbw.andobjviewer.Config.java
edu.dhbw.andobjviewer.InstructionsActivity.java
edu.dhbw.andobjviewer.ModelChooser.java
edu.dhbw.andobjviewer.graphics.LightingRenderer.java
edu.dhbw.andobjviewer.graphics.Model3D.java
edu.dhbw.andobjviewer.graphics.Renderer.java
edu.dhbw.andobjviewer.models.Group.java
edu.dhbw.andobjviewer.models.Material.java
edu.dhbw.andobjviewer.models.Model.java
edu.dhbw.andobjviewer.models.Vector3D.java
edu.dhbw.andobjviewer.parser.MtlParser.java
edu.dhbw.andobjviewer.parser.ObjParser.java
edu.dhbw.andobjviewer.parser.ParseException.java
edu.dhbw.andobjviewer.parser.SimpleTokenizer.java
edu.dhbw.andobjviewer.parser.Util.java
edu.dhbw.andobjviewer.util.ArrayIterator.java
edu.dhbw.andobjviewer.util.AssetsFileUtil.java
edu.dhbw.andobjviewer.util.BaseFileUtil.java
edu.dhbw.andobjviewer.util.FixedPointUtils.java
edu.dhbw.andobjviewer.util.MatrixUtils.java
edu.dhbw.andobjviewer.util.MemUtil.java
edu.dhbw.andobjviewer.util.SDCardFileUtil.java