ThreeJS: Remove object/mesh from scene by uuid

Viewed 611

I'm creating figures\meshes by createFigure(). Ideally, i need somehow store each uuid in the list where every element has a button/cross to delete the object from the scene by its stored uuid.

I'm freshman in three.js and it's hard to find even proper documentation\samples on this. Will be glad for help.

    <body>
 <ul id="uuidList" class="live-list">
</ul>

    <div class="controls">
        <form>
            <input class="scalar-input" type="text" id="params" placeholder="2,2,2" />
            <div class="dropdown">
                <select class="dropbtn" id="geometry">
                    <option value="cube">Cube</option>
                    <option value="sphere">Sphere</option>
                    <option value="pyramid">Pyramid</option>
                </select>
                <Button id="createButton" class="createbtn"> CREATE </Button>
            </div>
        </form>
    </div>
    <script type="module">

        import * as THREE from "https://threejs.org/build/three.module.js";
        import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

        // Receiving scalars
        let scalars;
        var a,b,c;
        const params = document.querySelector('input');
        const log = document.getElementById('values');
        params.addEventListener('input', showParams);
        function showParams(e) {
        scalars = e.target.value;
        if(typeof scalars === "string"){
            scalars = scalars.split(",");
            a = scalars[0];
            b = scalars[1];
            c = scalars[2];
        }
        }

        // Receiving shape
        const btn = document.querySelector('#createButton');
        const shape = document.querySelector('#geometry')
        btn.onclick = (event) => {
        event.preventDefault();
        createFigure(shape.value, a,b,c);
        };

        var mesh, renderer, scene, camera, controls;

        init();
        animate();


        //Creating figure based on received data
        function createFigure(shape, a,b,c) {

            if(shape == "sphere"){
            var geometry = new THREE.SphereGeometry(a,b,c);
            }
            if(shape == "cube") {
            var geometry = new THREE.BoxGeometry(a,b,c);
            }
            if(shape == "pyramid")
            var geometry = new THREE.ConeGeometry(a,b,c);
            // material
            var material = new THREE.MeshPhongMaterial( {
                color: 0x00ffff, 
                flatShading: true,
                transparent: true,
                opacity: 1,
            } );

            // mesh
            mesh = new THREE.Mesh( geometry, material );
            mesh.position.x = Math.random() * 2 - 1;
            mesh.position.y = Math.random() + 0.15;
            mesh.position.z = Math.random() * 2 - 1;
            // ( Math.random() - 0.5) * 1000; // alternative gives us negative numbers 
            mesh.position.multiplyScalar( 30 );
            scene.add( mesh );
            console.log(mesh.uuid);
            console.log(scene);
            
            var node = document.createElement("LI");   
            var textnode = document.createTextNode(mesh.uuid);
            node.appendChild(textnode);
            document.getElementById("uuidList").appendChild(node);
            // can successfully logout each uuid and add them to a list. don't know what to do next

        }

example Example on image, to add crosses/button on list item's and onclick deleting list item & object from scene by uuid

2 Answers

To delete Meshes by UUID, just add a click event listener to each node you make. Then use the method .getObjectById().

node.addEventListener("click", function() {
    const object = scene.getObjectById(mesh.uuid);
    scene.remove(object);
});

I solved it by doing this

        <a class="live-list" id="myList"></a>  //in body

At the end of createFigure() function i added following, so that every time function is called -> mesh is created and so creates new hyperlink

       <a id="uuidList" value="uuid"> "uuid" </a> // hyperlink construction
            var node = document.createElement("a"); //creating hyperlink tag
            var textnode = document.createTextNode(mesh.uuid); // with uuid as atext inside 
            node.appendChild(textnode);
            node.setAttribute("id", "uuidList"); // attribute "id" named "uuidlist"
            node.setAttribute("value", mesh.uuid); // attribute "value" with content of mesh.uuid that being created
            document.getElementById("myList").appendChild(node); //adding as a child to #myList

Then to my #idList i binding a button, -> onclick i reading value property of item in the list and by it mesh is being disposed by it's uuid.

  const btnd = document.querySelector('#myList');
        btnd.onclick = (event) => {  // creating event onclick for #myList
        event.preventDefault();
        let i = 2;
        x = document.getElementsByTagName("a")[i].getAttribute("value"); // defining that variable x is attribute value in a tag 
        var element = document.getElementsByTagName("a");
        element[i].parentNode.removeChild(element[i]); // deleting selected tag
        i++;
        console.log(x);
        console.log(scene);
        const object = scene.getObjectByProperty( 'uuid', x); // getting object by property uuid and x is uuid of an object that we want to delete and clicked on before
        object.geometry.dispose();
        object.material.dispose();
        scene.remove( object ); // disposing and deleting mesh from scene
        };

The code is no perfect and can be improved, but it's works. Check live code: https://kramzin.github.io/threejs-task/ enter image description here

Related