Generating indexed from non-indexed Geometry issue [SOLVED]

Maybe i just made a silly mistake, but i wrote a quick function to generate a indexed geometry from a non-indexed one for a test. But for some reasons it will be always wrong (a lot faces missing/wrong), while all vertices are only merged into an index.

Maybe you have some non-indexed geometry floating around to test. geometry is the non-indexed geometry for input and out should be a empty new THREE.BufferGeometry instance.

Edit: And as expected it was just a silly mistake, i’ve used signed ArrayBuffers instead unsigned ones.

function indexBuffer(geometry, out) {

    const vertices = {};
    const list = [];

    function KEY(v) {

        return Math.floor( v.x * 1000 ) + '_' + Math.floor( v.y * 1000 ) + '_'  + Math.floor( v.z * 1000 );

    }

    function VERTEX(v) {

        const id = KEY(v);

        if ( vertices[id] === undefined ) {

            vertices[id] = list.length;

            list.push(v);

        }

        return vertices[id];

    }

    const faces = geometry.faces;

    const type = faces.length * 3 > 65536 ? Int32Array : Int16Array;

    const array = new type(faces.length * 3);

    for ( let i = 0, l = faces.length; i < l; i ++ ) {

        const face = faces[i];

        array[i * 3    ] = VERTEX(geometry.vertices[face.a]);
        array[i * 3 + 1] = VERTEX(geometry.vertices[face.b]);
        array[i * 3 + 2] = VERTEX(geometry.vertices[face.c]);

    }


    out.index = new THREE.BufferAttribute(array, 1);


    const verticesArray = new Float32Array(list.length * 3);

    for ( let i = 0, l = list.length; i < l; i ++ ) {

        const vertex = list[i];

        verticesArray[i * 3    ] = vertex.x;
        verticesArray[i * 3 + 1] = vertex.y;
        verticesArray[i * 3 + 2] = vertex.z;

    }

    out.attributes.position = new THREE.BufferAttribute(verticesArray, 3);



}
1 Like

The answer to this has been posted here:

Summary below:
Freystar has written a code that can be used to convert non-indexed to indexed geometry, BUT three.js has later implemented a method that can help with this called BufferGeometryUtils.mergeVertices() which is the recommended approach right now.

import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";

documentation link:
https://threejs.org/docs/?q=buffergeom#examples/en/utils/BufferGeometryUtils.mergeVertices

I’m not sure why you’re answering this 6 year old post with another post of mine :face_with_hand_over_mouth:

1 Like

When I searched for this issue, I found this post the very first time, but did not see any response.
So I added a one for anyone who’ll check it in the future