Search in sources :

Example 1 with Mesh

use of org.vitrivr.cineast.core.data.m3d.Mesh in project cineast by vitrivr.

the class ModularMeshDecoder method getNext.

/**
 * Fetches the next piece of content of type T and returns it. This method can be safely invoked until complete() returns false. From which on this method will return null.
 *
 * @return Content of type T.
 */
@Override
public Mesh getNext() {
    final String contenttype = MimeTypeHelper.getContentType(this.inputFile.toFile());
    /* Try to detach decoder from the list of cached decoders. */
    Decoder<Mesh> decoder = this.cachedDecoders.get(contenttype);
    /* If decoder is null, create a new one. */
    if (decoder == null) {
        decoder = decoderForContenttype(contenttype);
    }
    /* If decoder is still null, return an emtpy Mesh. */
    if (decoder == null) {
        LOGGER.warn("Could not find mesh decoder for provided contenttype {}.", contenttype);
        return Mesh.EMPTY;
    } else {
        this.cachedDecoders.put(contenttype, decoder);
    }
    /* Initialize the decoder and return the decoded mesh. */
    decoder.init(this.inputFile, null, null);
    Mesh mesh = decoder.getNext();
    this.complete.set(true);
    return mesh;
}
Also used : Mesh(org.vitrivr.cineast.core.data.m3d.Mesh)

Example 2 with Mesh

use of org.vitrivr.cineast.core.data.m3d.Mesh in project cineast by vitrivr.

the class ModularMeshDecoder method convert.

/**
 * Converts a single file to a QueryContainer.
 *
 * @param path Path the file that should be converted.
 * @return QueryContainer for the specified file.
 */
@Override
public AbstractQueryTermContainer convert(Path path) {
    final String contenttype = MimeTypeHelper.getContentType(path.toFile());
    /* Try to detach decoder from the list of cached decoders. */
    Decoder<Mesh> decoder = this.cachedDecoders.get(contenttype);
    /* If decoder is null, create a new one. */
    if (decoder == null) {
        decoder = decoderForContenttype(contenttype);
    }
    /* If decoder is still null, return an emtpy Mesh. */
    if (decoder == null) {
        LOGGER.warn("Could not find mesh decoder for provided contenttype {}.", contenttype);
        return null;
    } else {
        this.cachedDecoders.put(contenttype, decoder);
    }
    /* Initialize the decoder and return the decoded mesh. */
    decoder.init(path, null, null);
    Mesh mesh = decoder.getNext();
    return new ModelQueryTermContainer(mesh);
}
Also used : ModelQueryTermContainer(org.vitrivr.cineast.core.data.query.containers.ModelQueryTermContainer) Mesh(org.vitrivr.cineast.core.data.m3d.Mesh)

Example 3 with Mesh

use of org.vitrivr.cineast.core.data.m3d.Mesh in project cineast by vitrivr.

the class STLMeshDecoder method readBinary.

/**
 * Reads a binary STL file.
 *
 * @param is   InputStream to read from.
 * @param skip Number of bytes to skip before reading the STL file.
 * @return Mesh
 * @throws IOException If an error occurs during reading.
 */
private Mesh readBinary(InputStream is, int skip) throws IOException {
    /* Prepare a ByteBuffer to read the rest of the STL file. */
    byte[] bytes = new byte[50];
    ByteBuffer buffer = ByteBuffer.wrap(bytes);
    buffer.order(ByteOrder.LITTLE_ENDIAN);
    /* Skip the STL header! */
    is.skip(skip);
    /* Read the bytes for the size (unsigned 32 bit int, little-endian). */
    byte[] sizeBytes = new byte[4];
    is.read(sizeBytes, 0, 4);
    long triangles = ((sizeBytes[0] & 0xFF)) | ((sizeBytes[1] & 0xFF) << 8) | ((sizeBytes[2] & 0xFF) << 16) | ((sizeBytes[3] & 0xFF) << 24);
    /* TODO: Properly handle models whose triangles > MAX_TRIANGLES. */
    if (triangles <= 0) {
        LOGGER.error("The number of triangles in the Mesh seems to be smaller than zero. This STL file is probably corrupt!");
        return null;
    } else if (triangles > MAX_TRIANGLES) {
        LOGGER.error("The number of triangles in the Mesh exceeds the limit that can currently be processed by STLMeshDecoder. The Mesh will be downsampled!");
        return null;
    }
    /* Prepare Mesh. */
    Mesh mesh = new Mesh((int) triangles, (int) triangles);
    /* Prepare helper structures. */
    TObjectIntHashMap<Vector3f> vertexBuffer = new TObjectIntHashMap<>();
    int index = 0;
    int[] vertexindices = new int[3];
    /* Now add all triangles. */
    for (int i = 0; i < triangles; i++) {
        /* Ready 48 bytes from the stream. */
        buffer.rewind();
        is.read(bytes);
        /* Read and ignore three floats. */
        buffer.getFloat();
        buffer.getFloat();
        buffer.getFloat();
        /* Add the vertices and the vertex-normal to the mesh. */
        for (int vidx = 0; vidx < 3; vidx++) {
            Vector3f vertex = new Vector3f(buffer.getFloat(), buffer.getFloat(), buffer.getFloat());
            if (!vertexBuffer.containsKey(vertex)) {
                mesh.addVertex(vertex);
                vertexBuffer.put(vertex, index);
                index++;
            }
            vertexindices[vidx] = vertexBuffer.get(vertex);
        }
        /* Add a new face to the Mesh. */
        if (!mesh.addFace(new Vector3i(vertexindices[0], vertexindices[1], vertexindices[2]))) {
            LOGGER.warn("Could not add face {}/{}/{} because index points to non-existing vertex.", vertexindices[0], vertexindices[1], vertexindices[2]);
        }
    }
    /* Closes the InputStream. */
    is.close();
    return mesh;
}
Also used : TObjectIntHashMap(gnu.trove.map.hash.TObjectIntHashMap) Vector3f(org.joml.Vector3f) Vector3i(org.joml.Vector3i) Mesh(org.vitrivr.cineast.core.data.m3d.Mesh) ByteBuffer(java.nio.ByteBuffer)

Example 4 with Mesh

use of org.vitrivr.cineast.core.data.m3d.Mesh in project cineast by vitrivr.

the class STLMeshDecoder method readAscii.

/**
 * Reads an ASCII STL file.
 *
 * @param is InputStream to read from.
 * @return Mesh
 * @throws IOException If an error occurs during reading.
 */
private Mesh readAscii(InputStream is) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    String line = null;
    /* Prepare empty mesh. */
    Mesh mesh = new Mesh(100, 100);
    /* Prepare helper structures. */
    TObjectIntHashMap<Vector3f> vertexBuffer = new TObjectIntHashMap<>();
    int index = 0;
    int[] vertexindices = new int[3];
    while ((line = br.readLine()) != null && !line.startsWith("endsolid")) {
        line = line.trim();
        /* Detect end of STL file. */
        if (line.startsWith("endsolid")) {
            break;
        }
        /* Detect begin of facet. */
        if (line.startsWith("facet normal ")) {
            int vidx = 0;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                /* Detect end of facet. */
                if (line.equals("endfacet")) {
                    break;
                }
                /* Detect vertex. */
                if (line.startsWith("vertex")) {
                    String[] splitVertex = line.split("\\s+");
                    Vector3f vertex = new Vector3f(Float.parseFloat(splitVertex[1]), Float.parseFloat(splitVertex[2]), Float.parseFloat(splitVertex[3]));
                    if (!vertexBuffer.containsKey(vertex)) {
                        mesh.addVertex(vertex);
                        vertexBuffer.put(vertex, index);
                        index++;
                    }
                    vertexindices[vidx] = vertexBuffer.get(vertex);
                    vidx++;
                }
            }
            /* Add a new face to the Mesh. */
            mesh.addFace(new Vector3i(vertexindices[0], vertexindices[1], vertexindices[2]));
        }
    }
    /* Close the buffered reader. */
    br.close();
    /* This covers the case, where the file starts with 'solid ' but is not an ASCII file. Unfortunately, such files do exist. */
    if (mesh.numberOfVertices() == 0) {
        LOGGER.warn("The provided ASCII STL file does not seem to contain any normals or vertices. Trying to decode it as binary STL even though it was marked as being ASCII.");
        InputStream newIs = Files.newInputStream(this.inputFile);
        return this.readBinary(newIs, 80);
    } else {
        return mesh;
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) TObjectIntHashMap(gnu.trove.map.hash.TObjectIntHashMap) InputStream(java.io.InputStream) Vector3f(org.joml.Vector3f) BufferedReader(java.io.BufferedReader) Vector3i(org.joml.Vector3i) Mesh(org.vitrivr.cineast.core.data.m3d.Mesh)

Example 5 with Mesh

use of org.vitrivr.cineast.core.data.m3d.Mesh in project cineast by vitrivr.

the class MeshColoringUtil method normalColoring.

public static void normalColoring(WritableMesh mesh) {
    Vector3f axis = new Vector3f(1.0f, 0.0f, 0.0f);
    Vector3fc center = mesh.barycenter();
    Mesh.Vertex farthestVertex = MeshMathUtil.farthestVertex(mesh, center);
    float ds_max = center.distance(farthestVertex.getPosition());
    for (int i = 0; i < mesh.numberOfVertices(); i++) {
        float hue = (float) (axis.angle(mesh.getVertex(i).getNormal()) / Math.PI);
        float saturation = center.distance(mesh.getVertex(i).getPosition()) / ds_max;
        Color color = Color.getHSBColor(hue, saturation, 1.0f);
        mesh.updateColor(i, color);
    }
}
Also used : Vector3fc(org.joml.Vector3fc) Vector3f(org.joml.Vector3f) Color(java.awt.Color) Mesh(org.vitrivr.cineast.core.data.m3d.Mesh) WritableMesh(org.vitrivr.cineast.core.data.m3d.WritableMesh)

Aggregations

Mesh (org.vitrivr.cineast.core.data.m3d.Mesh)16 Vector3f (org.joml.Vector3f)10 Vector3i (org.joml.Vector3i)6 WritableMesh (org.vitrivr.cineast.core.data.m3d.WritableMesh)6 ReadableMesh (org.vitrivr.cineast.core.data.m3d.ReadableMesh)5 IOException (java.io.IOException)4 Vector3fc (org.joml.Vector3fc)4 TObjectIntHashMap (gnu.trove.map.hash.TObjectIntHashMap)3 BufferedReader (java.io.BufferedReader)3 InputStream (java.io.InputStream)3 InputStreamReader (java.io.InputStreamReader)3 Color (java.awt.Color)2 Vector4i (org.joml.Vector4i)2 JsonNode (com.fasterxml.jackson.databind.JsonNode)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 BufferedImage (java.awt.image.BufferedImage)1 File (java.io.File)1 ByteBuffer (java.nio.ByteBuffer)1 DMatrixRMaj (org.ejml.data.DMatrixRMaj)1 Matrix4f (org.joml.Matrix4f)1