UI element with hierarchical object tree

Hello Everyone,
I am fairly new to threejs and I am looking for a particular way to display the names of all objects in a scene.
I would like to have an “object-tree” that lists all objects in the scene and can show how objects ae grouped together.
SImilar to what is done in this example:
BIM-Architectural Model with object-tree

There is also an object tree like this in the threejs-editor called “Outliner”:
image

However, these examples seem way too involved for my use case. I would ideally have a very simple way of doing that without trying to hack out the outliner from the editor.

I just need to show the nested list, without the need to drag or regroup items. Collapsing the list would be a plus.

Is there an open source project somewhere that fits this description? Searching for “Tree” or “Outliner” in combination with threejs has not given good results. Is there another word for an inspection element like this?

Any help or references would be appreciated. Thank you in advance.

study the composite and visitor patterns.

Thanks for the suggestion, How exactly would this help in my case? I am aware of this design pattern but I dont see how I could use it to create an object-tree

I’m current creating an outline in my project.

Basically, when an object is added a function is called to updated the html interface. You can group the created objects in a THREE.Group or store in a variable for interface’s list reference.

An THREE.Object().name can be assigned too.

For what it is worth, the code below creates a basic tree structure. So you can just recursively parse your scene, and create the html for the tree from that.

    <!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <style>
        .node {
            margin-left: 50px;
        }
        .ntitle {
            padding-left:24px;
            cursor: pointer;
            background: url('closed.svg') no-repeat left;
            background-size: 30px 30px;
            background-position-x:-5px;
        }
            .ntitle.open {
                background: url('open.svg') no-repeat left;
                background-size: 30px 30px;
                background-position-x: -5px;
            }
        .ntitle:hover{
            background-color:azure;
        }
        .children {
            margin-left: 10px;
        }
        .hide {
            display:none;
        }
    </style>
</head>
<body>
    <div class="node">
        <div class="ntitle">Main</div>
            <div class="children hide">
                <div class="node">
                    <div class="ntitle">ListItem 1</div>
                        <div class="children hide">
                            <div class="ntitle">ListItem a</div>
                            <div class="ntitle">ListItem b</div>
                        </div>
                    </div>
                <div class="node">
                    <div class="ntitle">ListItem 2</div>
                </div>
                    <div class="node">
                        <div class="ntitle">ListItem 3</div>
                    </div>
                    </div>
        </div>
    <script type="text/javascript">
        $('.ntitle').click(function () {
            var p = $(this);
            var c = p.parent().find('.children:first')
            if (c.hasClass('hide')) {
                c.removeClass('hide');
                p.addClass('open');
            }
            else {
                c.addClass('hide');
                p.removeClass('open');
           }
        })
    </script>
</body>
</html>

So with code like this:

<div class="objtree"></div>
<script type="text/javascript">
    function parseScene(scene) {
        var h = check(scene);
        $('.objtree').html(h);
    }
    function check(obj) {
        var html = '';
        var name = obj.name ? obj.name +' (' +obj.type+')' : obj.type;
        html +='<div class="node">'
        html += '<div class="ntitle">' + name + '</div>';
        if (obj.children) {
            html += '<div class="children hide">';
            for (var i = 0; i < obj.children.length; i++) {
                html += check(obj.children[i],)
            }
            html += '</div>';
        }
        html += "</div>";
        return html;
    }
    function assignEvent() {
        $('.ntitle').click(function () {
            var p = $(this);
            var c = p.parent().find('.children:first')
            if (c.hasClass('hide')) {
                c.removeClass('hide');
                p.addClass('open');
            }
            else {
                c.addClass('hide');
                p.removeClass('open');
            }
        })
    }
        parseScene(scene);
        assignEvent();

</script>

Thank you very much! I will try this!