Хотите частично визуализировать объект вокселя? - PullRequest
0 голосов
/ 17 июня 2020

У меня есть 3D-массив [250] [150] [250], который представляет человеческое тело (в основном это объект вокселя). Каждый элемент содержит значения от 0 до 255, где 255 означает, что элемент пуст и должен быть проигнорирован, а 0–254 представляют разные органы (например, кожу, легкие и протравливание), поэтому должны быть нарисованы. В своей программе я записываю данные элементов, которые должны быть отрисованы, в 2 текстовых файла (vertices.txt и index.txt). vertices.txt содержит координаты x, y и z всех вершин вокселя, которые должны быть нарисованы, а index.txt содержит все индексы.

Я могу визуализировать все тело со всеми органами, что не является проблемой. enter image description here

Пример из vertices.txt:

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

Пример из index.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

Моя проблема в том, что я не знать, как визуализировать определенную c часть тела (например: скажем, я хочу визуализировать только легкие). Как я могу это сделать? Нужно ли мне создавать index.txt и vetices.txt для каждого отдельного органа (в основном делая каждый орган отдельным я sh)?

EDIT: код, который отвечает за запись в vertices.txt и индексы .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();
}   

Me sh. 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);
}
...