Edge Collapse with assimp

2019-09-07 13:15发布

问题:

I'm trying to implement the edge collapse in my game engine, there is a problem caused by Assimp. The indices that parsed from face.mNumIndices is always the increment order indexing.

When I check the list of indices, the value should be sort of 0,1,2,3,4....,999... . But I know this is some kind of mechanism that used by Assimp, and the object are rendered all right. But there is another issue on Mesh Simplication, I could not generate the half-edge structure for this indices. I stuck on this a couple of days, and have no answer. Should I give up Assimp? Any advise is appreciated.

Edit: My vertices are shared between faces, The code I used to get the data here.

BasicRenderModel* AssimpLoader::ProcessMeshBasicVersion(aiMesh * mesh, const aiScene * scene)
{
    //std::vector<Vertex> vertices;
    float *vertices = new float[mesh->mNumVertices * 3];
    int vertexLength = mesh->mNumVertices * 3;
    float *normals = new float[mesh->mNumVertices * 3];
    int normalLength = mesh->mNumVertices * 3;
    float *texCoords = new float[mesh->mNumVertices * 2];
    int texCoordLength = mesh->mNumVertices * 2;
    std::vector<int> indicesList;
    int *indices;
    int indexLength;

    //std::vector<Texture> textures;
    std::map<TextureType, std::vector<Texture>> textures;
    for (GLuint i = 0; i < mesh->mNumVertices; i++)
    {
        // Process vertex positions, normals and texture coordinates
        vertices[i * 3] = mesh->mVertices[i].x;
        vertices[i * 3 + 1] = mesh->mVertices[i].y;
        vertices[i * 3 + 2] = mesh->mVertices[i].z;
        normals[i * 3] = mesh->mNormals[i].x;
        normals[i * 3 + 1] = mesh->mNormals[i].y;
        normals[i * 3 + 2] = mesh->mNormals[i].z;
        if (mesh->mTextureCoords[0]) // Does the mesh contain texture coordinates?
        {
            texCoords[i * 2] = mesh->mTextureCoords[0][i].x;
            texCoords[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
        }
        else
            texCoords[i * 2] = texCoords[i * 2 + 1] = 0.0f;
        Debug::Log("vertex: " + std::to_string(vertices[i * 3]) + "," + std::to_string(vertices[i * 3 + 1]) + "," + std::to_string(vertices[i * 3 + 2]));
    }
    // Process indices
    for (GLuint i = 0; i < mesh->mNumFaces; i++)
    {
        aiFace face = mesh->mFaces[i];
        for (GLuint j = 0; j < face.mNumIndices; j++)
            indicesList.push_back(face.mIndices[j]);
    }
    indices = new int[indicesList.size()];
    indexLength = indicesList.size();
    for (int i = 0; i < (int)indicesList.size(); i++)
        indices[i] = indicesList[i];

    return this->loader.LoadRenderModel(vertices, vertexLength, indices, indexLength, texCoords, texCoordLength, normals, normalLength);
}

And the result vertices of this object and indices that generated by the code above is here

Compare the result and obj file. For the tree object, the obj file has 624 vertices, but Assimp has 927 vertices, and indices from obj are 310(lines) * 3 = 930, but the Indices read from Assimp are 927 indices. I thought Assimp process the data behind, and generate the specified indices and vertices.

If I need to recalculate indices, that means I need to check all vertices for each vertex to find which are the same and construct the indices..? Could not figure out how to slove this problem..

回答1:

There has two important things to make the algorithm work with Assimp Importer.

  1. The model should be shared vertex with faces, If the model is not, it should be done with some options in 3D model software. The tree object that I provide in the question section, I need to remove doubles (remove duplicated vertices) in blender and the normal should be just one.

  2. The other thing need to be noticed that the postprocess option with assimp. check the Assimp documentation, there is a flag called aiProcess_JoinIdenticalVertices, if this is not enable, Assimp would generate the totally unique Indices for unique vertices. There is more information at here.