/*
 * www.javagl.de - Utilities
 *
 * Copyright (c) 2008-2011 Marco Hutter - http://www.javagl.de
 */
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import de.javagl.utils.obj.FloatTuple;
import de.javagl.utils.obj.Obj;
import de.javagl.utils.obj.ObjFace;
import de.javagl.utils.obj.ObjGroup;
import de.javagl.utils.obj.ObjReader;
import de.javagl.utils.obj.ObjWriter;
import de.javagl.utils.obj.impl.DefaultObj;
import de.javagl.utils.obj.impl.DefaultObjReader;
import de.javagl.utils.obj.impl.DefaultObjWriter;
import de.javagl.utils.obj.impl.ObjUtils;

/**
 * A sample demonstrating the basic usage of the OBJ utilities
 */
public class ObjSample
{
    /**
     * Entry point of this sample
     * 
     * @param args Not used
     * @throws IOException If an IO error occurs
     */
    public static void main(String[] args) throws IOException
    {
        // Read an OBJ from a file
        DefaultObj obj = new DefaultObj();
        ObjReader objReader = new DefaultObjReader();
        InputStream inputStream = new FileInputStream("example.obj");
        objReader.read(inputStream, obj);
        inputStream.close();
        
        System.out.println("Read obj:");
        printInfo(obj);
        
        // Access some basic elements of the OBJ:
        FloatTuple vertex = obj.getVertex(0);
        FloatTuple normal = obj.getNormal(0);
        FloatTuple texCoord = obj.getTexCoord(0);
        ObjFace face = obj.getFace(0);
        ObjGroup mtlGroup = obj.getMaterialGroup(0);
        System.out.println("vertex  : "+vertex);
        System.out.println("normal  : "+normal);
        System.out.println("texCoord: "+texCoord);
        System.out.println("Face: "+face);
        System.out.println("First material group: "+mtlGroup);
        System.out.println();
        

        // Create an OBJ that contains only triangles
        DefaultObj triangulated = new DefaultObj();
        ObjUtils.triangulate(obj, triangulated);
                    
        System.out.println("Triangulated obj:");
        printInfo(triangulated);

        // Write the triangulated OBJ
        ObjWriter objWriter = new DefaultObjWriter();
        OutputStream outputStream = 
            new FileOutputStream("example_triangulated.obj");
        objWriter.write(obj, outputStream);
        outputStream.close();

        // Create an OBJ where the texture coordinates
        // for all vertices are unique.
        DefaultObj unique = new DefaultObj();
        ObjUtils.assertUniqueTextureCoords(triangulated, unique, null, 1e-5f);
        
        System.out.println("Obj with unique texture coordinates:");
        printInfo(unique);
        
        // Obtain the first group of the triangulated OBJ
        // and convert it into an OBJ
        DefaultObj part = new DefaultObj();
        ObjGroup objGroup = triangulated.getGroup(0);
        ObjUtils.groupToObj(triangulated, objGroup, part, null);

        System.out.println("First group of obj file:");
        printInfo(part);

        // Write the first group of the OBJ as a single OBJ file
        outputStream = new FileOutputStream("example_part.obj");
        objWriter.write(part, outputStream);
        outputStream.close();
    }
    
    private static void printInfo(Obj obj)
    {
        System.out.println("Vertices:  "+obj.getNumVertices());
        System.out.println("Normals:   "+obj.getNumNormals());
        System.out.println("TexCoords: "+obj.getNumTexCoords());
        System.out.println("Faces:     "+obj.getNumFaces());
        System.out.println();
    }

}

