Hot to partially render a voxel object?

71 Views Asked by At

I do have 3D array[250][150][250] which represents human body (basically it is a voxel object). Each element contain values from 0 to 255, where 255 means that an elements is empty and should be ignored and 0-254 represent different organs (like skin, lung and etch) hence should be drawn. In my program I writing the data of elements that should be drawn in 2 txt files (vertices.txt and indices.txt). vertices.txt contain x,y and z coordinates of all voxel vertices that should be drawn and indices.txt contain all indices.

I am able to render whole body with all organs that is not the problem.enter image description here

Example from vertices.txt:

193 68 0 // coordinates of a voxel
193 68 1
193 69 0
193 69 1

Example from indices.txt:

4 5 7 4 6 7  // face of a voxel. Each face is represented by 2 triangles. Hence, we need 6 indices.
2 3 7 2 6 7
0 4 6 0 2 6

My problem is that I do not know how to render a specific part of a body (For example: lets say that I want to render only lungs). How can I do that? Do I have to create indices.txt and vetices.txt for each individual organ (basically making each organ as a separate mesh)?

EDIT: Code that is responsible for writing into vertices.txt and indices.txt.

void writePhantomDataToThefile(std::ofstream& verticies_out_file, std::ofstream& indicies_out_file)
{
    verticies_out_file.open(vertices, std::ofstream::out | std::ofstream::trunc);
    indicies_out_file.open(indices, std::ofstream::out | std::ofstream::trunc);

    unsigned elements = 0;

    for (int z = 0; z < zMax; z++)
    {
        for (int y = 0; y < yMax; y++)
        {
            for (int x = 0; x < xMax; x++)
            {
                if (phantom->voxel[x][y][z] == emptyVoxel) // empty voxel is 255
                {
                    continue;
                }
                else
                {
                    if ((x != 0 && x != (xMax - 1)) && (y != 0 && y != (yMax - 1)) && (z != 0 && z != (zMax - 1)) &&
                        (phantom->voxel[x + 1][y][z] != emptyVoxel) && (phantom->voxel[x - 1][y][z] != emptyVoxel) && (phantom->voxel[x][y + 1][z] != emptyVoxel) &&
                        (phantom->voxel[x][y - 1][z] != emptyVoxel) && (phantom->voxel[x][y][z + 1] != emptyVoxel) && (phantom->voxel[x][y][z - 1] != emptyVoxel))
                    { // this part of code skips elements if is surrounded by elements != 255
                        continue; // basically right now I am drawing the skin of a body
                    }

                    verticies_out_file << x << " " << y << " " << z << std::endl;
                    verticies_out_file << x << " " << y << " " << z + 1 << std::endl;
                    verticies_out_file << x << " " << y + 1 << " " << z << std::endl;
                    verticies_out_file << x << " " << y + 1 << " " << z + 1 << std::endl;
                    verticies_out_file << x + 1 << " " << y << " " << z << std::endl;
                    verticies_out_file << x + 1 << " " << y << " " << z + 1 << std::endl;
                    verticies_out_file << x + 1 << " " << y + 1 << " " << z << std::endl;
                    verticies_out_file << x + 1 << " " << y + 1 << " " << z + 1 << std::endl;

                    if (x != 0 && x != (xMax - 1))
                    {
                        if (phantom->voxel[x - 1][y][z] != emptyVoxel)
                        {
                            indicies_out_file << (elements * 8) << " " << (elements * 8 + 2) << " " << (elements * 8 + 3) << " "
                            << (elements * 8) << " " << (elements * 8 + 1) << " "<< (elements * 8 + 3) << std::endl; // left face
                        }
                        if (phantom->voxel[x + 1][y][z] != emptyVoxel)
                        {
                            indicies_out_file << (elements * 8 + 4) << " " << (elements * 8 + 5) << " "<< (elements * 8 + 7) << " " 
                            << (elements * 8 + 4) << " "<< (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // right face
                        }
                    }
                    else
                    {
                        if (x == 0)
                        {
                            indicies_out_file << (elements * 8) << " " << (elements * 8 + 2) << " "<< (elements * 8 + 3) << " "
                            << (elements * 8) << " "<< (elements * 8 + 1) << " "<< (elements * 8 + 3) << std::endl; // left face
                        }
                        if (x == (xMax - 1))
                        {
                            indicies_out_file << (elements * 8 + 4) << " "<< (elements * 8 + 5) << " "<< (elements * 8 + 7) << " "
                            << (elements * 8 + 4) << " " << (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // right face
                        }
                    }

                    if (y != 0 && y != (yMax - 1))
                    {
                        if (phantom->voxel[x][y - 1][z] != emptyVoxel)
                        {
                            indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " "<< (elements * 8 + 4) << " " 
                            << (elements * 8 + 1) << " " << (elements * 8) << " "<< (elements * 8 + 4) << std::endl; // bottom face
                        }
                        if (phantom->voxel[x][y + 1][z] != emptyVoxel)
                        {
                            indicies_out_file << (elements * 8 + 2) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << " " 
                            << (elements * 8 + 2) << " " << (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // top face
                        }
                    }
                    else
                    {
                        if (y == 0)
                        {
                            indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " " << (elements * 8 + 4) << " " 
                            << (elements * 8 + 1) << " " << (elements * 8) << " " << (elements * 8 + 4) << std::endl; // bottom face
                        }

                        if (y == (yMax - 1))
                        {
                            indicies_out_file << (elements * 8 + 2) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << " " 
                            << (elements * 8 + 2) << " " << (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // top face
                        }
                    }

                    if (z != 0 && z != (zMax - 1))
                    {
                        if (phantom->voxel[x][y][z - 1] != emptyVoxel)
                        {
                            indicies_out_file << (elements * 8) << " " << (elements * 8 + 4) << " " << (elements * 8 + 6) << " " 
                            << (elements * 8) << " " << (elements * 8 + 2) << " " << (elements * 8 + 6) << std::endl;  // front face
                        }

                        if (phantom->voxel[x][y][z + 1] != emptyVoxel)
                        {
                            indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " " << (elements * 8 + 7) << " "
                            << (elements * 8 + 1) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << std::endl; // back face
                        }
                    }
                    else
                    {
                        if (z == 0)
                        {
                            indicies_out_file << (elements * 8) << " " << (elements * 8 + 4) << " " << (elements * 8 + 6) << " "
                            << (elements * 8) << " " << (elements * 8 + 2) << " " << (elements * 8 + 6) << std::endl;  // front face
                        }

                        if (z == (zMax - 1))
                        {
                            indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " " << (elements * 8 + 7) << " "
                            << (elements * 8 + 1) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << std::endl; // back face
                        }
                    }

                    elements++;
                }
            }
        }
    }

    verticies_out_file.close();
    indicies_out_file.close();
}   

Mesh.cpp

#include "Mesh.h"
#include <iostream>
#include <sstream>
#include <fstream>

Mesh::Mesh()
{
    loaded = false;
}

Mesh::~Mesh()
{
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);
    glDeleteBuffers(1, &ibo);
}

void Mesh::loadVertices(std::string fileName)
{
    int item = 0, n = 0, x = 0, y = 0;
    std::ifstream is(fileName, std::ifstream::binary);

    if (is) {
        is.seekg(0, is.end);
        int length = is.tellg();
        is.seekg(0, is.beg);

        char* buffer = new char[length];

        is.read(buffer, length);

        is.close();

        for (unsigned int i = 0; i < is.gcount(); i++)
        {
            switch (buffer[i])
            {
            case '\r':
                break;
            case '\n':
            {
                vertices.push_back(glm::vec3(y, item, x));
                n = 0;
                item = 0;
                break;
            }
            case ' ':
            {
                n++;
                if (n == 1)
                {
                    x = item;
                }
                else
                {
                    y = item;
                }

                item = 0;
                break;
            }
            case '0': case '1': case '2': case '3':
            case '4': case '5': case '6': case '7':
            case '8': case '9':
                item = 10 * item + buffer[i] - '0';
                break;
            default:
                std::cerr << "Bad format\n";
            }
        }

        delete[] buffer;
    }
}

void Mesh::loadIndices(std::string fileName)
{
    int item = 0;
    std::ifstream is(fileName, std::ifstream::binary);

    if (is) {
        is.seekg(0, is.end);
        int length = is.tellg();
        is.seekg(0, is.beg);

        char* buffer = new char[length];

        is.read(buffer, length);

        is.close();

        for (unsigned int i = 0; i < is.gcount(); i++)
        {
            switch (buffer[i])
            {
            case '\r':
                break;
            case '\n':
            {
                indicies.push_back(item);
                item = 0;
                break;
            }
            case ' ':
            {
                indicies.push_back(item);
                item = 0;
                break;
            }
            case '0': case '1': case '2': case '3':
            case '4': case '5': case '6': case '7':
            case '8': case '9':
                item = 10 * item + buffer[i] - '0';
                break;
            default:
                std::cerr << "Bad format\n";
            }
        }

        delete[] buffer;
    }
}


bool Mesh::loadOBJ()
{
    loadVertices("Phantom Data/FA_vertices.txt");
    loadIndices("Phantom Data/FA_indices.txt");

    initBuffers();

    return (loaded = true);
}

void Mesh::draw()
{
    if (!loaded) return;


    glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, nullptr);
    glBindVertexArray(0);
}

void Mesh::initBuffers()
{

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), NULL);
    glEnableVertexAttribArray(0);

    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicies.size() * sizeof(GLuint), &indicies[0], GL_STATIC_DRAW);

    glBindVertexArray(0);
}
0

There are 0 best solutions below