Three.js: Printing debug view of scene graph?

Created on 9 Mar 2017  Β·  15Comments  Β·  Source: mrdoob/three.js

Is there any existing feature for printing the scene tree to the console, e.g. for debugging? I'm finding it a bit time-consuming to expand node.children recursively in the JS Console. If not, I wanted to propose something along the lines of:

SceneUtils.log( node );
. <Scene>
β”œβ”€β”€ <Object3D>
β”‚Β Β  └── joint_1 <Bone>
β”‚Β Β      └── joint_2 <Bone>
β”‚Β Β          └── joint_3 <Bone>
β”œβ”€β”€ fancy_character <SkinnedMesh>
β”œβ”€β”€ <PointLight>
β”œβ”€β”€ <AmbientLight>
└── bookshelf <Mesh>

Most helpful comment

I would like to suggest console.group() for outputting the scene graph.
Here for the moment a very basic demo:

(function printGraph( obj ) {

    console.group( ' <' + obj.type + '> ' + obj.name );

    obj.children.forEach( printGraph );

    console.groupEnd();

} ( scene ) );  

If you open the dev tools in Chrome, you get the fully expanded tree, but you have also the possibility to collapse it partly to fit your needs.

Chrome, initial state (expanded):

scenegraph_chrome

Chrome, partly collapsed:

scenegraph_chrome_collapsed

A little downside: Firefox currently supports no collapsing, but I’ve tested it with FF Nightly, and in Nightly it works the same as in Chrome.

Current FF (52):

scenegraph_firefox_52

FF Nigthly:

scenegraph_firefox_nightly

All 15 comments

How about this one?

scene.traverse(function(obj) {
  var s = '';
  var obj2 = obj;
  while(obj2 !== scene) {
    s += '-';
    obj2 = obj2.parent;
  }
  console.log(s + obj.type + ' ' + obj.name);
});

If Object3D had depth property, the code would be much simpler...

A slight mod...

scene.traverse( function ( obj ) {

    var s = '|___';

    var obj2 = obj;

    while ( obj2 !== scene ) {

        s = '\t' + s;

        obj2 = obj2.parent;

    }

    console.log( s + obj.name + ' <' + obj.type + '>' );

} );

Thanks, either of these works great. πŸ™‚

Does this seem appropriate for e.g. SceneUtils, or should I just bookmark the snippet?

As for me, bookmaking is good enough (just my opinion).

I think it's pretty handy!
How about adding it to Object3D so we could do... scene.log() or mesh.log()...?

Not bad. I wanna make PR.

What information should we display?

  • type
  • name

Anything else?

I'm thinking if we wanna pass the property list .log() displays, like this...

scene.log( [ 'position', 'quaternion' ] );

I would like to suggest console.group() for outputting the scene graph.
Here for the moment a very basic demo:

(function printGraph( obj ) {

    console.group( ' <' + obj.type + '> ' + obj.name );

    obj.children.forEach( printGraph );

    console.groupEnd();

} ( scene ) );  

If you open the dev tools in Chrome, you get the fully expanded tree, but you have also the possibility to collapse it partly to fit your needs.

Chrome, initial state (expanded):

scenegraph_chrome

Chrome, partly collapsed:

scenegraph_chrome_collapsed

A little downside: Firefox currently supports no collapsing, but I’ve tested it with FF Nightly, and in Nightly it works the same as in Chrome.

Current FF (52):

scenegraph_firefox_52

FF Nigthly:

scenegraph_firefox_nightly

@jostschmithals that's a nice trick! along similar lines, if I add the %o placeholder, the console will print the entire tree expanded, while showing each individual node collapsed. You can expand e.g. Mesh to see its properties.

(function printGraph( obj ) {

    console.group( ' <%o> ' + obj.name, obj );

    obj.children.forEach( printGraph );

    console.groupEnd();

} ( scene ) );

screen shot 2017-03-09 at 10 50 50 am

I just wanted to suggest this further enhancement too, but I think then it would be more eye-friendly to choose the order from your first post (to avoid nesting):

(function printGraph( obj ) {

    console.group(obj.name + ' <%o> ', obj);

    obj.children.forEach( printGraph );

    console.groupEnd();

}(scene));

scenegraph_doublecollapsing

Unfortunately it seems that FF doesn't understand the %o-thing in the same manner :-(

The script I posted above appears to handle scenes with many children a bit better as it counts -- rather than repeats -- duplicate lines. Try this three.js example, which has 700+ child meshes.

|___ <Scene>
    |___ <Group>
        |___Bip01_Pelvis <Object3D>
        ...
        ...
    |___ <AmbientLight>
    |___ <PointLight>
725     |___ <Mesh>

... although it offsets the duplicates a bit.

Indeed – this is not only β€ža bit”, but much more convenient in such a scenario (which I had not in mind)!

Would it perhaps make sense to have the possibility of switching between both types of implementation (combined in one method)? - I guess that the imaginable use cases can be very divergent, so that both implementations could be useful in different places.

too bad I can't "favorite" issues on github

For others interested, the three.js inspector Chrome extension also shows a nice interactive scene graph.

Was this page helpful?
0 / 5 - 0 ratings