These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Adding a simple 3D model to an existing model

geojunkie
geojunkie's picture
Registered: Mar 7 2010
Posts: 7
Answered

I am currently using Acrobat Pro Extended v9.3.1 on windows XP. I am trying to add a simple model of a 3D disk into an existing model using the 3D javascript API and then move the disk to wherever the user clicks the mouse. The existing model is embedded in a 3D PDF that was created from a VRML file and the model I am trying to add to it via javascript was created using Google SketchUp to export a Collada file that was then converted into a U3D file using Adobe 3D Reviewer. I know that in order to add a model to another model I must first attach it to the PDF as a resource which I have done by right clicking the existing model, selecting properties, and adding the U3D file using the controls on the resources tab. The relevant javascript I am using to add the model to the existing model is:

var modelResource = new Resource( "pdf://disk.u3d" );
var model = scene.addModel( modelResource );

This code does indeed add the disk model to my existing model, however while I would expect that the "model" variable would then contain a reference to the top level node of the disk model whose transform I could then translate to a mouse click location, it does not, "model" is actually null.

I am obviously getting the following error in the Javascript console window upon trying to use the resulting node:

Line: 24: Code: 21(0x15): null is not an object

I believe that I am either missing an initialization step or there is a problem with my process of creating my disk model u3d file using SketchUp and Reviewer.

I suppose my question is what might I be doing wrong and why am I getting Null when I believe that I should be getting a reference to the top level node of my added model?

I know that this can be done because I have seen several PDF's that do this successfully. Any help or suggestions are always appreciated. Thanks.

My Product Information:
Acrobat 3D 9.2, Windows
UVSAR
UVSAR's picture
Expert
Registered: Oct 29 2008
Posts: 1357
Re-collect the node object by using scene.meshes.getByName() with the name of the top-level node in your newly-loaded file. Ignore the return value of the scene.addModel() call; it's broken.

Remember though - if the loaded model has a root-level group then it's not a mesh (it's a Node3), so you can't use the getByName() method on it.

If you're loading a model and don't know the names inside it, remember that the new model is always added at the end of the sceneObjectList - so if you store scene.meshes.count in a variable X, load the model, and call scene.meshes.getByIndex(X), it will return the new node. If the model is grouped it'll return the first true mesh node within the new model.
geojunkie
geojunkie's picture
Registered: Mar 7 2010
Posts: 7
Can't thank you enough for the fast and accurate reply. I'm on a tight deadline and this answer just opened a lot of doors for us. I have one more related question. When my model gets added it appears that the lighting for the cumulative model changes (perhaps to the light source of the node being added?). Anyway do you have any idea why this might be happening?
UVSAR
UVSAR's picture
Expert
Registered: Oct 29 2008
Posts: 1357
If a loaded model has lights in it, those are added to the scene along with the mesh (as are cameras, animations, materials, etc.) - so if the viewport is using "lights from file", you will indeed see the cumulative effect. Afraid there's no option on the addModel() method to filter out certain node types, but you can always traverse through the scene.lights object (another sceneObjectList) and turn off the new entries using the same store-previous-count method to find the first new one. You can't delete a light, just as you can't delete a mesh node - but you can set .brightness=0 to turn it off.

The other option of course is to switch to one of the Acrobat preset light schemes, but if you're using lights-from-file for a particular reason, the above is the only way to get back to where you were before the load event.


Sorry this is all a bit klunky, but the 3D JS API is not the most polished of creations. It'll be better next time!
geojunkie
geojunkie's picture
Registered: Mar 7 2010
Posts: 7
Thank you again for your advise. It has been infinitely helpful on this project. I want to clarify something you said in your last post:

"You can't delete a light, just as you can't delete a mesh node - but you can set .brightness=0 to turn it off."

I am now in need of being able to delete a model node that I just inserted. I am trying to use

scene.meshes.removeItem(node);

to accomplish this, where "node" is a node reference that I cached in an array.

Are you saying that this will not achieve the purpose of removing the mesh from the model? What I am seeing is that it appears to remove the first item I try to remove but it will not remove the rest. If I try to remove all the meshes that I added then I actually end up with no models at all (At least none that are rendering any more). I want to make sure that my application is cleaning up after itself properly by removing any artifacts that I have inserted, either one-by-one or altogether.
UVSAR
UVSAR's picture
Expert
Registered: Oct 29 2008
Posts: 1357
Correct - you absolutely cannot delete nodes of any type from a scene, only hide them. The methods of SceneObjectList (removeItem, etc.) just disconnect the node from the list, but it stays loaded and orphaned in the scene - and can then cause no end of mayhem as you can't re-address it. All you can do is hide mesh nodes by setting .visible=false, and there's no garbage collection.

It does mean the user can turn them back on again, but only if they're bright enough to find the menus.