const pointer troubles

Hello

I have come across an issue which I can not seem to figure out.

I'm writing some 3D code and I started using ASSIMP to load a simple 3DS scene.

The code to load a scene is provided as such:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
bool DoTheImportThing( const std::string& pFile)
{
  // Create an instance of the Importer class
  Assimp::Importer importer;
  // And have it read the given file with some example postprocessing
  // Usually - if speed is not the most important aspect for you - you'll 
  // propably to request more postprocessing than we do in this example.
  const aiScene* scene = importer.ReadFile( pFile, 
        aiProcess_CalcTangentSpace       | 
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  |
        aiProcess_SortByPType);
  
  // If the import failed, report it
  if( !scene)
  {
    DoTheErrorLogging( importer.GetErrorString());
    return false;
  }
  // Now we can access the file's contents. 
  DoTheSceneProcessing( scene);
  // We're done. Everything will be cleaned up by the importer destructor
  return true;
}


It works really well, except, I am not able to "retain" the scene object outside the scope of this function.

What I'd like to do, is import the scene, and pass it, or some of its members to some of my other functions, in this case, I want the Mesh and it's members so I can have my graphics engine draw it.

According to the documentation, when importer is finished, it will destroy all of its contents, along with the scene and all of its data, which leaves the pointer pointing to, well nothing useful.

This is something I have not come across, and I thought a bit of experimenting would get me through this easily, but I'm stuck :(
I tried creating scenes and importers as globals, but nothing seems to work.

I could really use some help as to how to retain the data I am looking for so I can pass it onto other components of my project.

I'm using VS2010 Pro, and I'm coding with PhysX, Irrlicht, and ASSIMP at the moment trying to import a very simple 3DS file.

Any help will be greatly appreciated

Regards

xp
I don't know ASSIMP. But I think you should try copying the scene object to some global one???

Hahahaaa.........(That's impossible, isn't it)?
As I said I don't know assimp
Hi Aceix

That is exactly what I'm trying to figure out, the ASSIMP lib does not provide a copy constructor, and I'm trying to "not" write one of my own as the scene data is fairly extensive.

There has to be a way to do this, I'm not expert enough to figure it out....

One thing that comes to mind is I could do all the work inside the load function, but this would break/complicate a lot of other things.

xp
Someone can correct me but I think that since you are declaring and defining aiScene as you are it is just local temp storage. Much like if you declared

 
const char * refString = "Fiddlesticks";


refString would not be accessible outside the scope of its local assignment.

Would it work to create an aiScene with new() and then make the assignment and pass it as a return value? (Keeping in mind you'll need to deal with the delete() somewhere down the line)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
aiScene* DoTheImportThing( const std::string& pFile)
{
  Assimp::Importer importer;
  aiScene* scene = new aiScene;
        scene = sceimporter.ReadFile( pFile, 
        aiProcess_CalcTangentSpace       | 
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  |
        aiProcess_SortByPType);
  
  if(!scene)
  {
    DoTheErrorLogging( importer.GetErrorString());
  } else {
    DoTheSceneProcessing(scene);
  }
  return &scene;
}
Last edited on
Hi Texan40

I completely agree with your thinking, and I thought this approach would solve this issue, but, it does not.

I had the function redefined to do exactly what you describe, but, as soon as the function is done, any reference I make to scene gets deleted as well.

I have never come across behaviour like this, it makes sense, but I don't know how to work with it/around it.

I also tried creating a global importer, the same thing happened, it really has me stumped. Weather I declare an entire scene outside, or just the meshes I need, everything gets wiped clean the moment this function completes.

It's really mind boggling....

xp
Hi Gulkan,

Yes that's the reference page for it.

And if you take a look at the Destructor comments, this is what is says:

Assimp::Importer::~Importer ( )
Destructor.

The object kept ownership of the imported data, which now will be destroyed along with the object.

And my question is how do I keep the imported data, copy, move elsewhere, anything really.

xp
closed account (zb0S216C)
xp190 wrote:
"It works really well, except, I am not able to "retain" the scene object outside the scope of this function."

I would declare "scene" static, and return a reference to it. However, you would have to either return a reference to a constant "aiScene", or, return a pointer to a constant "aiScene." For example:

1
2
3
4
5
int &StaticData()
{
    static int Data(0);
    return(Data);
}


Wazzak
Last edited on
I really can't see why you cannot create the importer object - perhaps in the main function and then pass a reference to to to those functions that need it.

The importer class has a GetScene function - so you can get a pointer to the sece at any time you want.
This greatly simplifies the DoTheImportThing function.

((Any function that uses the importer object can check whether it has a valid scene by useing the GetScene function in order top avoid any bad scene pointer
access crashes)

I was think about something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//prototype
void  DoTheImportThing( Assimp::Importer&  importer, const std::string& pFile);

// prototype for some other functionm that makes use of
//our scene importer.

void some_other_function(Assimp::Importer&  importer);
	
	

int main()
{

	Assimp::Importer  importer;
	DoTheImportThing(importer, string("whateverfile.name");
	//Check if the scene loaded ok.
	if (!importer.GetScene())
	{
	//errror occurred
	//deal with it
	}
	
	//other code if the scene loaded successfully.
	
}


void  DoTheImportThing( Assimp::Importer&  importer, const std::string& pFile)
{
  // Have the Importer read the  given file with some example postprocessing
 
  //We don't even need to check whther the scen loaded at this stage.
        importer.ReadFile( pFile, 
        aiProcess_CalcTangentSpace       | 
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  |
        aiProcess_SortByPType);
  
}

void some_other_function(Assimp::Importer&  importer)
{
    //Do stuff with the importer
    //we can check if the importer object has a valid scene 
    if ( !importer.getScene() )
    {
        //serious problem scene does not exist
        //take evasive action
    }
    
    //other code
}	

aiScene* Assimp::Importer::GetOrphanedScene()


I thank you kindly gentleman....

GetOrphanedScene() combined with a global reference to importer passed to the loading function did the trick.

Here is the final function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool LoadScene(Assimp::Importer& importer, const std::string& pFile)
{
  //Assimp::Importer importer;
   const aiScene* scene = importer.ReadFile( pFile, 
        aiProcess_CalcTangentSpace       | 
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  |
        aiProcess_SortByPType);

	if( !scene)
	{
		printf(importer.GetErrorString());
		return false;
	}
	return true;

}



Once again, thank you all kindly :)

xp
Topic archived. No new replies allowed.