Question

I am trying to use ASSIMP to extract the vertex/normal/face information from a ply file and then render it using OpenGL. Following is the code :

void PLYParser::importFile(std::string sFilePath)
{
    const aiScene* scene = aiImportFile (sFilePath.c_str(), aiProcess_Triangulate); // TRIANGLES!

    if (!scene)
    {
        std::cerr << "ERROR: reading mesh %s\n" << sFilePath << std::endl;
        return;
    }

    printf ("  %i animations\n", scene->mNumAnimations);
    printf ("  %i cameras\n", scene->mNumCameras);
    printf ("  %i lights\n", scene->mNumLights);
    printf ("  %i materials\n", scene->mNumMaterials);
    printf ("  %i meshes\n", scene->mNumMeshes);
    printf ("  %i textures\n", scene->mNumTextures);

      for (unsigned int m_i = 0; m_i < scene->mNumMeshes; m_i++)
      {
          const aiMesh* mesh = scene->mMeshes[m_i];
          printf ("    %i vertices in mesh\n", mesh->mNumVertices);
          g_point_count = mesh->mNumVertices;
          for (unsigned int v_i = 0; v_i < mesh->mNumVertices; v_i++)
          {
            if (mesh->HasPositions ())
            {
              const aiVector3D* vp = &(mesh->mVertices[v_i]);
              printf ("      vp %i (%f,%f,%f)\n", v_i, vp->x, vp->y, vp->z);
            }
            if (mesh->HasNormals ())
            {
              const aiVector3D* vn = &(mesh->mNormals[v_i]);
              printf ("      vn %i (%f,%f,%f)\n", v_i, vn->x, vn->y, vn->z);
            }
            if (mesh->HasTextureCoords (0))
            {
              const aiVector3D* vt = &(mesh->mTextureCoords[0][v_i]);
              printf ("      vt %i (%f,%f)\n", v_i, vt->x, vt->y);
            }
            if (mesh->HasTangentsAndBitangents ())
            {
              // NB: could store/print tangents here
            }

            if( mesh->HasFaces() )
            {
                const struct aiFace * vf = &(mesh->mFaces[m_i]);
                if (vf->mNumIndices == 3)
                {
                   printf ("      vf (%f,%f,%f)\n", vf->mIndices[0],vf->mIndices[1], vf->mIndices[2]);
                }
            }
          }
        }

      std::cout << "Parsing over" << std::endl ;
}

The vertex values are printing fine, but the face related information is kind of garbage, something of this sort :

vp 5107 (0.003326,0.079200,0.001920)
vf (0.000000,-0.000000,26815622223676999148426976713858144581866377154979840994523259353566101584147672957460702289212360863380556296293016572911077072166495943380764853993996288.000000)

Q1. Am I doing something wrong in the face related code ?

Q2. Also, there seems to be no normal related information in any of the ply files i parse. I have to manually calculate the normal for everything. Do ply have no normal information at all ?

P.S. : I have tried the code on several different ply files, I still get garbage values for the face information.


Edit 1 :

for (unsigned int m_i = 0; m_i < scene->mNumMeshes; m_i++)
      {
          const aiMesh* mesh = scene->mMeshes[m_i];
          printf ("    %i vertices in mesh\n", mesh->mNumVertices);
          g_point_count = mesh->mNumVertices;

          for (unsigned int v_i = 0; v_i < mesh->mNumFaces; v_i++)
          {
              if (mesh->HasFaces())
              {
                  for (unsigned int f_i = 0; f_i < mesh->mNumFaces; f_i++)
                  {
                      const struct aiFace* vf = mesh->mFaces + f_i;

                      if (vf->mNumIndices == 3)
                      {
                          printf("      vf (%u,%u,%u)\n", vf->mIndices[0], vf->mIndices[1], vf->mIndices[2]);
                      }
                  }
              }
          }
        }

Am getting the alternate numbers as the output by changing code to above -

  vf (0,1,2)
  vf (3,4,5)
  vf (6,7,8)
  vf (9,10,11)
  vf (12,13,14)
  vf (15,16,17)
  ..
  ..
  and so on.
Was it helpful?

Solution

A1.

First issue:

printf ("      vf (%f,%f,%f)\n", vf->mIndices[0], vf->mIndices[1], vf->mIndices[2]);

The type of vf->mIndices is unsigned int*, so the format specifier %f is wrong, it should be %u. Try this instead:

printf ("      vf (%u,%u,%u)\n", vf->mIndices[0], vf->mIndices[1], vf->mIndices[2]);

Second issue:

You need to iterate over the list of faces of the mesh just like it is currently done for the list of vertices. Simply remove the current code dealing with the faces in the vertex loop, and add another loop for faces (at the same level as the one for vertices), like this:

for (unsigned int v_i = 0; v_i < mesh->mNumVertices; v_i++)
{
    // ...
}

if (mesh->HasFaces())
{
    for (unsigned int f_i = 0; f_i < mesh->mNumFaces; f_i++)
    {
        const struct aiFace* vf = mesh->mFaces + f_i;

        if (vf->mNumIndices == 3)
        {
            printf("      vf (%u,%u,%u)\n", vf->mIndices[0], vf->mIndices[1], vf->mIndices[2]);
        }
    }
}

A2.

There can be normal information specified for each vertex (3 additional float properties per vertex element named nx, ny and nz) in a PLY file. Since the format is flexible, normal per face could also be specified in a similar way. It all depends on what has been exported by the tool used to generate this file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top