0

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..

Community
  • 1
  • 1
Tokenyet
  • 4,063
  • 2
  • 27
  • 43
  • Increasing indices are fine. What is the question? Do you think multiple vertices should be merged into one but they don't? That would be problemmatic without seeing data. – keltar Nov 30 '16 at 07:29
  • @keltar ,for using edge collapse, I could not find the opposite of edge because of there is no opposite index pair to find, or I misunderstood the edge collapse? – Tokenyet Nov 30 '16 at 08:02
  • If you want to merge vertices between faces then yes, these indices alone are not mergeable. It really depends on how you decided what you count as 'vertex' - some software thinks it is only position, while GL/D3D/assimp/etc. assembles all attributes into single vertex, and if at least one number is different - there are different vertices. So I'll ask once again - are you 100% sure your data have vertices that are shared between faces (this includes position, normal, texture coordinates, etc..)? If so, add data sample that illustrates your problem. – keltar Nov 30 '16 at 08:24
  • Perhaps it would be better with an example - hard edged cube have not 8 'full' vertices (with all attributes) but 24, while soft edged may have 8. If you don't care about other attributes and only want position - then you can quite easily recalculate indices only for positions, but after that you'll have to recalculate other attributes to match your resulting model. – keltar Nov 30 '16 at 08:30
  • @keltar, I add more information about it, but not sure what information I miss to provide. For more testing, I also add the vertex one by one to OpenMesh's Mesh structure and do the decimation job, but the problem is the same, the incremental order of indices could not use the edge collapse job. By the way, you refer to recalculate indices, but I thought that's hard to construct either :( , the last thing, I temporary ignore the normal and texCoord, just want to check my edge collapse algorithm works... – Tokenyet Nov 30 '16 at 14:49
  • 1
    I'm not sure how to say it, because I already did (and another question you linked to did, too). Your obj is flat-shaded/hard-edged, for each face vertex normal points in different direction, even if vertex position is the same. Assimp loads model in GL/D3D-friendly format, so there is no way it can keep these positions as the same vertex. At least one attribute (normal) is different, - hence there are different vertices. Assimp says your obj have 624 unique vertices; when I've imported this model to blender, smoothed it and exported again - it became 157, now it can be folded. – keltar Dec 01 '16 at 06:08

1 Answers1

0

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.

Tokenyet
  • 4,063
  • 2
  • 27
  • 43