Question

I've got a problem with returning this const pointer. Using the debugger showed me that the scene is correctly imported and stored in variable scene. After returning scene, the content pointed by scene is lost and cannot be accessed by the class calling loadData().

const aiScene* IOHandler::loadData(const std::string& pFile){
    Assimp::Importer importer;

    const aiScene* scene = importer.ReadFile(pFile,
    aiProcess_CalcTangentSpace      |
    aiProcess_Triangulate           |
    aiProcess_JoinIdenticalVertices |
    aiProcess_SortByPType);

    return scene;
}

(Importer and aiScene(struct) are part of the assimp library and cannot be modified)

I assume that the scene is stored on the stack, the return call resets the stackpointer and the content is lost. How to handle such a problem in c++?

Was it helpful?

Solution

You forgot to read the documentation.

The scene is owned by the Importer, so it will be destroyed when that goes out of scope. Return importer.GetOrphanedScene() to take ownership, and remember to delete it when you've finished with it.

Alternatively, you could store the importer somewhere more permanent; but that might not work too well if you need to import and use many scenes at the same time.

OTHER TIPS

My guess is Assimp::Importer owns the resource returned by ReadFile, so when importer goes out of scope, the resource (memory) is released, and you end up returning a dangling pointer. You can pass it by parameter, or make it static so that it persists beyond the function scope, or allocate scene dynamically, copying the contents of what ReadFile returns -

const aiScene* scene = new aiScene(*importer.ReadFile(pFile,
aiProcess_CalcTangentSpace      |
aiProcess_Triangulate           |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType));

You have misinterpreted the problem. The problem isn't that the pointer is local & gets destroyed. The problem is that Assimp::Importer's destructor destroys what the pointer is pointing to. Since the Assimp::Importer object gets destroyed at the end of the function, the pointer is now pointing at invalid stuff.

Why do you need a loadData function? Why not use ReadFile as suggested here - http://assimp.sourceforge.net/lib_html/usage.html

Alternately, the solution to your problem would be ensure that the Importer object doesn't go out of scope till your done using the aiScene.

One possible way may be this - make the Importer object a parameter to the loadData method.

const aiScene* IOHandler::loadData(Assimp::Importer & importer, 
           const std::string& pFile)
{
          const aiScene* scene = importer.ReadFile(pFile,
          aiProcess_CalcTangentSpace        |
          aiProcess_Triangulate         |
          aiProcess_JoinIdenticalVertices |
          aiProcess_SortByPType);

     return scene;
}

The calling code would look like this.

{
    ........
    Assimp::Importer imp;
    const aiScene * p = loadData(imp, pFile);
    // use aiScene 
    ........
    // Importer object goes out of scope here.
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top