Search in sources :

Example 1 with IntArray

use of org.sunflow.util.IntArray in project joons-renderer by joonhyublee.

the class FileMesh method tesselate.

public PrimitiveList tesselate() {
    if (filename.endsWith(".ra3")) {
        try {
            UI.printInfo(Module.GEOM, "RA3 - Reading geometry: \"%s\" ...", filename);
            File file = new File(filename);
            FileInputStream stream = new FileInputStream(filename);
            MappedByteBuffer map = stream.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length());
            map.order(ByteOrder.LITTLE_ENDIAN);
            IntBuffer ints = map.asIntBuffer();
            FloatBuffer buffer = map.asFloatBuffer();
            int numVerts = ints.get(0);
            int numTris = ints.get(1);
            UI.printInfo(Module.GEOM, "RA3 -   * Reading %d vertices ...", numVerts);
            float[] verts = new float[3 * numVerts];
            for (int i = 0; i < verts.length; i++) {
                verts[i] = buffer.get(2 + i);
            }
            UI.printInfo(Module.GEOM, "RA3 -   * Reading %d triangles ...", numTris);
            int[] tris = new int[3 * numTris];
            for (int i = 0; i < tris.length; i++) {
                tris[i] = ints.get(2 + verts.length + i);
            }
            stream.close();
            UI.printInfo(Module.GEOM, "RA3 -   * Creating mesh ...");
            return generate(tris, verts, smoothNormals);
        } catch (FileNotFoundException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - file not found", filename);
        } catch (IOException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - I/O error occured", filename);
        }
    } else if (filename.endsWith(".obj")) {
        int lineNumber = 1;
        try {
            UI.printInfo(Module.GEOM, "OBJ - Reading geometry: \"%s\" ...", filename);
            FloatArray verts = new FloatArray();
            IntArray tris = new IntArray();
            FileReader file = new FileReader(filename);
            BufferedReader bf = new BufferedReader(file);
            String line;
            while ((line = bf.readLine()) != null) {
                if (line.startsWith("v")) {
                    String[] v = line.split("\\s+");
                    verts.add(Float.parseFloat(v[1]));
                    verts.add(Float.parseFloat(v[2]));
                    verts.add(Float.parseFloat(v[3]));
                } else if (line.startsWith("f")) {
                    String[] f = line.split("\\s+");
                    if (f.length == 5) {
                        tris.add(Integer.parseInt(f[1]) - 1);
                        tris.add(Integer.parseInt(f[2]) - 1);
                        tris.add(Integer.parseInt(f[3]) - 1);
                        tris.add(Integer.parseInt(f[1]) - 1);
                        tris.add(Integer.parseInt(f[3]) - 1);
                        tris.add(Integer.parseInt(f[4]) - 1);
                    } else if (f.length == 4) {
                        tris.add(Integer.parseInt(f[1]) - 1);
                        tris.add(Integer.parseInt(f[2]) - 1);
                        tris.add(Integer.parseInt(f[3]) - 1);
                    }
                }
                if (lineNumber % 100000 == 0) {
                    UI.printInfo(Module.GEOM, "OBJ -   * Parsed %7d lines ...", lineNumber);
                }
                lineNumber++;
            }
            file.close();
            UI.printInfo(Module.GEOM, "OBJ -   * Creating mesh ...");
            return generate(tris.trim(), verts.trim(), smoothNormals);
        } catch (FileNotFoundException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - file not found", filename);
        } catch (NumberFormatException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - syntax error at line %d", lineNumber);
        } catch (IOException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - I/O error occured", filename);
        }
    } else if (filename.endsWith(".stl")) {
        try {
            UI.printInfo(Module.GEOM, "STL - Reading geometry: \"%s\" ...", filename);
            FileInputStream file = new FileInputStream(filename);
            DataInputStream stream = new DataInputStream(new BufferedInputStream(file));
            file.skip(80);
            int numTris = getLittleEndianInt(stream.readInt());
            UI.printInfo(Module.GEOM, "STL -   * Reading %d triangles ...", numTris);
            long filesize = new File(filename).length();
            if (filesize != (84 + 50 * numTris)) {
                UI.printWarning(Module.GEOM, "STL - Size of file mismatch (expecting %s, found %s)", Memory.bytesToString(84 + 14 * numTris), Memory.bytesToString(filesize));
                return null;
            }
            int[] tris = new int[3 * numTris];
            float[] verts = new float[9 * numTris];
            for (int i = 0, i3 = 0, index = 0; i < numTris; i++, i3 += 3) {
                // skip normal
                stream.readInt();
                stream.readInt();
                stream.readInt();
                for (int j = 0; j < 3; j++, index += 3) {
                    tris[i3 + j] = i3 + j;
                    // get xyz
                    verts[index + 0] = getLittleEndianFloat(stream.readInt());
                    verts[index + 1] = getLittleEndianFloat(stream.readInt());
                    verts[index + 2] = getLittleEndianFloat(stream.readInt());
                }
                stream.readShort();
                if ((i + 1) % 100000 == 0) {
                    UI.printInfo(Module.GEOM, "STL -   * Parsed %7d triangles ...", i + 1);
                }
            }
            file.close();
            // create geometry
            UI.printInfo(Module.GEOM, "STL -   * Creating mesh ...");
            if (smoothNormals) {
                UI.printWarning(Module.GEOM, "STL - format does not support shared vertices - normal smoothing disabled");
            }
            return generate(tris, verts, false);
        } catch (FileNotFoundException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - file not found", filename);
        } catch (IOException e) {
            Logger.getLogger(FileMesh.class.getName()).log(Level.SEVERE, null, e);
            UI.printError(Module.GEOM, "Unable to read mesh file \"%s\" - I/O error occured", filename);
        }
    } else {
        UI.printWarning(Module.GEOM, "Unable to read mesh file \"%s\" - unrecognized format", filename);
    }
    return null;
}
Also used : FileNotFoundException(java.io.FileNotFoundException) FloatBuffer(java.nio.FloatBuffer) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) FileInputStream(java.io.FileInputStream) FloatArray(org.sunflow.util.FloatArray) MappedByteBuffer(java.nio.MappedByteBuffer) IntArray(org.sunflow.util.IntArray) BufferedInputStream(java.io.BufferedInputStream) IntBuffer(java.nio.IntBuffer) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) File(java.io.File)

Example 2 with IntArray

use of org.sunflow.util.IntArray in project joons-renderer by joonhyublee.

the class ShaveRibParser method parseIntArray.

private int[] parseIntArray(Parser p) throws IOException {
    IntArray array = new IntArray();
    boolean done = false;
    do {
        String s = p.getNextToken();
        if (s.startsWith("[")) {
            s = s.substring(1);
        }
        if (s.endsWith("]")) {
            s = s.substring(0, s.length() - 1);
            done = true;
        }
        array.add(Integer.parseInt(s));
    } while (!done);
    return array.trim();
}
Also used : IntArray(org.sunflow.util.IntArray)

Example 3 with IntArray

use of org.sunflow.util.IntArray in project joons-renderer by joonhyublee.

the class KDTree method build.

@Override
public void build(PrimitiveList primitives) {
    UI.printDetailed(Module.ACCEL, "KDTree settings");
    UI.printDetailed(Module.ACCEL, "  * Max Leaf Size:  %d", maxPrims);
    UI.printDetailed(Module.ACCEL, "  * Max Depth:      %d", MAX_DEPTH);
    UI.printDetailed(Module.ACCEL, "  * Traversal cost: %.2f", TRAVERSAL_COST);
    UI.printDetailed(Module.ACCEL, "  * Intersect cost: %.2f", INTERSECT_COST);
    UI.printDetailed(Module.ACCEL, "  * Empty bonus:    %.2f", EMPTY_BONUS);
    UI.printDetailed(Module.ACCEL, "  * Dump leaves:    %s", dump ? "enabled" : "disabled");
    Timer total = new Timer();
    total.start();
    primitiveList = primitives;
    // get the object space bounds
    bounds = primitives.getWorldBounds(null);
    int nPrim = primitiveList.getNumPrimitives(), nSplits = 0;
    BuildTask task = new BuildTask(nPrim);
    Timer prepare = new Timer();
    prepare.start();
    for (int i = 0; i < nPrim; i++) {
        for (int axis = 0; axis < 3; axis++) {
            float ls = primitiveList.getPrimitiveBound(i, 2 * axis + 0);
            float rs = primitiveList.getPrimitiveBound(i, 2 * axis + 1);
            if (ls == rs) {
                // flat in this dimension
                task.splits[nSplits] = pack(ls, PLANAR, axis, i);
                nSplits++;
            } else {
                task.splits[nSplits + 0] = pack(ls, OPENED, axis, i);
                task.splits[nSplits + 1] = pack(rs, CLOSED, axis, i);
                nSplits += 2;
            }
        }
    }
    task.n = nSplits;
    prepare.end();
    Timer t = new Timer();
    IntArray tempTree = new IntArray();
    IntArray tempList = new IntArray();
    tempTree.add(0);
    tempTree.add(1);
    t.start();
    // sort it
    Timer sorting = new Timer();
    sorting.start();
    radix12(task.splits, task.n);
    sorting.end();
    // build the actual tree
    BuildStats stats = new BuildStats();
    buildTree(bounds.getMinimum().x, bounds.getMaximum().x, bounds.getMinimum().y, bounds.getMaximum().y, bounds.getMinimum().z, bounds.getMaximum().z, task, 1, tempTree, 0, tempList, stats);
    t.end();
    // write out final arrays
    // free some memory
    task = null;
    tree = tempTree.trim();
    tempTree = null;
    this.primitives = tempList.trim();
    tempList = null;
    total.end();
    // display some extra info
    stats.printStats();
    UI.printDetailed(Module.ACCEL, "  * Node memory:    %s", Memory.sizeof(tree));
    UI.printDetailed(Module.ACCEL, "  * Object memory:  %s", Memory.sizeof(this.primitives));
    UI.printDetailed(Module.ACCEL, "  * Prepare time:   %s", prepare);
    UI.printDetailed(Module.ACCEL, "  * Sorting time:   %s", sorting);
    UI.printDetailed(Module.ACCEL, "  * Tree creation:  %s", t);
    UI.printDetailed(Module.ACCEL, "  * Build time:     %s", total);
    if (dump) {
        try {
            UI.printInfo(Module.ACCEL, "Dumping mtls to %s.mtl ...", dumpPrefix);
            FileWriter mtlFile = new FileWriter(dumpPrefix + ".mtl");
            int maxN = stats.maxObjects;
            for (int n = 0; n <= maxN; n++) {
                float blend = (float) n / (float) maxN;
                Color nc;
                if (blend < 0.25) {
                    nc = Color.blend(Color.BLUE, Color.GREEN, blend / 0.25f);
                } else if (blend < 0.5) {
                    nc = Color.blend(Color.GREEN, Color.YELLOW, (blend - 0.25f) / 0.25f);
                } else if (blend < 0.75) {
                    nc = Color.blend(Color.YELLOW, Color.RED, (blend - 0.50f) / 0.25f);
                } else {
                    nc = Color.MAGENTA;
                }
                mtlFile.write(String.format("newmtl mtl%d\n", n));
                float[] rgb = nc.getRGB();
                mtlFile.write("Ka 0.1 0.1 0.1\n");
                mtlFile.write(String.format("Kd %.12g %.12g %.12g\n", rgb[0], rgb[1], rgb[2]));
                mtlFile.write("illum 1\n\n");
            }
            FileWriter objFile = new FileWriter(dumpPrefix + ".obj");
            UI.printInfo(Module.ACCEL, "Dumping tree to %s.obj ...", dumpPrefix);
            dumpObj(0, 0, maxN, new BoundingBox(bounds), objFile, mtlFile);
            objFile.close();
            mtlFile.close();
        } catch (IOException e) {
            Logger.getLogger(KDTree.class.getName()).log(Level.SEVERE, null, e);
        }
    }
}
Also used : Timer(org.sunflow.system.Timer) IntArray(org.sunflow.util.IntArray) FileWriter(java.io.FileWriter) Color(org.sunflow.image.Color) BoundingBox(org.sunflow.math.BoundingBox) IOException(java.io.IOException)

Example 4 with IntArray

use of org.sunflow.util.IntArray in project joons-renderer by joonhyublee.

the class UniformGrid method build.

@Override
public void build(PrimitiveList primitives) {
    Timer t = new Timer();
    t.start();
    this.primitives = primitives;
    int n = primitives.getNumPrimitives();
    // compute bounds
    bounds = primitives.getWorldBounds(null);
    // create grid from number of objects
    bounds.enlargeUlps();
    Vector3 w = bounds.getExtents();
    double s = Math.pow((w.x * w.y * w.z) / n, 1 / 3.0);
    nx = MathUtils.clamp((int) ((w.x / s) + 0.5), 1, 128);
    ny = MathUtils.clamp((int) ((w.y / s) + 0.5), 1, 128);
    nz = MathUtils.clamp((int) ((w.z / s) + 0.5), 1, 128);
    voxelwx = w.x / nx;
    voxelwy = w.y / ny;
    voxelwz = w.z / nz;
    invVoxelwx = 1 / voxelwx;
    invVoxelwy = 1 / voxelwy;
    invVoxelwz = 1 / voxelwz;
    UI.printDetailed(Module.ACCEL, "Creating grid: %dx%dx%d ...", nx, ny, nz);
    IntArray[] buildCells = new IntArray[nx * ny * nz];
    // add all objects into the grid cells they overlap
    int[] imin = new int[3];
    int[] imax = new int[3];
    int numCellsPerObject = 0;
    for (int i = 0; i < n; i++) {
        getGridIndex(primitives.getPrimitiveBound(i, 0), primitives.getPrimitiveBound(i, 2), primitives.getPrimitiveBound(i, 4), imin);
        getGridIndex(primitives.getPrimitiveBound(i, 1), primitives.getPrimitiveBound(i, 3), primitives.getPrimitiveBound(i, 5), imax);
        for (int ix = imin[0]; ix <= imax[0]; ix++) {
            for (int iy = imin[1]; iy <= imax[1]; iy++) {
                for (int iz = imin[2]; iz <= imax[2]; iz++) {
                    int idx = ix + (nx * iy) + (nx * ny * iz);
                    if (buildCells[idx] == null) {
                        buildCells[idx] = new IntArray();
                    }
                    buildCells[idx].add(i);
                    numCellsPerObject++;
                }
            }
        }
    }
    UI.printDetailed(Module.ACCEL, "Building cells ...");
    int numEmpty = 0;
    int numInFull = 0;
    cells = new int[nx * ny * nz][];
    int i = 0;
    for (IntArray cell : buildCells) {
        if (cell != null) {
            if (cell.getSize() == 0) {
                numEmpty++;
                cell = null;
            } else {
                cells[i] = cell.trim();
                numInFull += cell.getSize();
            }
        } else {
            numEmpty++;
        }
        i++;
    }
    t.end();
    UI.printDetailed(Module.ACCEL, "Uniform grid statistics:");
    UI.printDetailed(Module.ACCEL, "  * Grid cells:          %d", cells.length);
    UI.printDetailed(Module.ACCEL, "  * Used cells:          %d", cells.length - numEmpty);
    UI.printDetailed(Module.ACCEL, "  * Empty cells:         %d", numEmpty);
    UI.printDetailed(Module.ACCEL, "  * Occupancy:           %.2f%%", 100.0 * (cells.length - numEmpty) / cells.length);
    UI.printDetailed(Module.ACCEL, "  * Objects/Cell:        %.2f", (double) numInFull / (double) cells.length);
    UI.printDetailed(Module.ACCEL, "  * Objects/Used Cell:   %.2f", (double) numInFull / (double) (cells.length - numEmpty));
    UI.printDetailed(Module.ACCEL, "  * Cells/Object:        %.2f", (double) numCellsPerObject / (double) n);
    UI.printDetailed(Module.ACCEL, "  * Build time:          %s", t.toString());
}
Also used : Timer(org.sunflow.system.Timer) IntArray(org.sunflow.util.IntArray) Vector3(org.sunflow.math.Vector3)

Example 5 with IntArray

use of org.sunflow.util.IntArray in project joons-renderer by joonhyublee.

the class BoundingIntervalHierarchy method build.

@Override
public void build(PrimitiveList primitives) {
    this.primitives = primitives;
    int n = primitives.getNumPrimitives();
    UI.printDetailed(Module.ACCEL, "Getting bounding box ...");
    bounds = primitives.getWorldBounds(null);
    objects = new int[n];
    for (int i = 0; i < n; i++) {
        objects[i] = i;
    }
    UI.printDetailed(Module.ACCEL, "Creating tree ...");
    int initialSize = 3 * (2 * 6 * n + 1);
    IntArray tempTree = new IntArray((initialSize + 3) / 4);
    BuildStats stats = new BuildStats();
    Timer t = new Timer();
    t.start();
    buildHierarchy(tempTree, objects, stats);
    t.end();
    UI.printDetailed(Module.ACCEL, "Trimming tree ...");
    tree = tempTree.trim();
    // display stats
    stats.printStats();
    UI.printDetailed(Module.ACCEL, "  * Creation time:  %s", t);
    UI.printDetailed(Module.ACCEL, "  * Usage of init:  %6.2f%%", (double) (100.0 * tree.length) / initialSize);
    UI.printDetailed(Module.ACCEL, "  * Tree memory:    %s", Memory.sizeof(tree));
    UI.printDetailed(Module.ACCEL, "  * Indices memory: %s", Memory.sizeof(objects));
}
Also used : IntArray(org.sunflow.util.IntArray) Timer(org.sunflow.system.Timer)

Aggregations

IntArray (org.sunflow.util.IntArray)5 Timer (org.sunflow.system.Timer)3 IOException (java.io.IOException)2 BufferedInputStream (java.io.BufferedInputStream)1 BufferedReader (java.io.BufferedReader)1 DataInputStream (java.io.DataInputStream)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileNotFoundException (java.io.FileNotFoundException)1 FileReader (java.io.FileReader)1 FileWriter (java.io.FileWriter)1 FloatBuffer (java.nio.FloatBuffer)1 IntBuffer (java.nio.IntBuffer)1 MappedByteBuffer (java.nio.MappedByteBuffer)1 Color (org.sunflow.image.Color)1 BoundingBox (org.sunflow.math.BoundingBox)1 Vector3 (org.sunflow.math.Vector3)1 FloatArray (org.sunflow.util.FloatArray)1