Slice BufferGeometry v125 and above

I was looking for any way to slice the geometry at for example, every vertex greater than Z:100 will be removed, and every X,Y bigger than 200 for example.

I was using V127 of threejs.

Actually I was trying with this code, but I was missing some step:
Before “Slice at z: 100”
image

After applying my actual code
image

As you can see it connects the removed vertex with the 0,0,0 position.

There is my code:

const positions = (this.mesh.geometry as THREE.BufferGeometry).attributes.position.array as Array<number>

        for (let i = 0; i < positions.length; i += 3) {

            if(positions[i +2] > 100) {
                positions[i] = null;
                positions[i + 1] = null;
                positions[i + 2] = null;
            }

        }

        (this.mesh.geometry as THREE.BufferGeometry).attributes.position.needsUpdate = true

/cc

This kind of vertex manipulating is problematic since you will mess up the face definitions of your geometry. Faces require three vertices in three.js (since they are always triangles). If you remove a vertex without defining a replacement, you produce undefined triangle data.

Since buffer attributes are fixed sized, you can not remove data from a buffer or perform any resizing operation in general. You have to create new buffer attributes and a new geometry. Alternatively, you move all “removed” vertices at the end of the buffers and define via drawRange what parts of the geometry should be rendered.

1 Like

Hi @Mugen87 ,

And the best way to move the vertex is inside the loop? I was trying to do that, but without success, i’ll keep trying, if you have some fast idea how to do can you tell me?

const positions: Float32Array = (this.mesh.geometry as THREE.BufferGeometry).attributes.position.array as Float32Array

    let total = positions.length;

    

    for (let i = 0; i < positions.length; i += 3) {

        let x = positions[i];

        let y = positions[i + 1];

        let z = positions[i + 2];

        let nextX = positions[i + 3];

        let nextY = positions[i + 4];

        let nextZ = positions[i + 5];

        if(z > 100) {

            positions[i] = nextX;

            positions[i + 1] = nextY;

            positions[i + 2] = nextZ;

            positions[i + 3] = null;

            positions[i + 4] = null;

            positions[i + 5] = null;

            total -= 3;

        }

        if(z == null) {

            positions[i] = nextX;

            positions[i + 1] = nextY;

            positions[i + 2] = nextZ;

            positions[i+3] = null;

            positions[i+4] = null;

            positions[i+5] = null;

        }

    }

    (this.mesh.geometry as THREE.BufferGeometry).attributes.position.needsUpdate = true

    this.mesh.geometry.setDrawRange(0, total);

Hi @Mugen87 how are you?

I was “removing” the 3 points of the vertex, but it keeps showing some weird triangles, what I’m missing?

Regards,

Before:

imagen

After:

imagen

Code:
const positions: Float32Array = (this.mesh.geometry as THREE.BufferGeometry).attributes.position.array as Float32Array

for (let i = 0; i < positions.length; i += 3) {

         let x = positions[i];
        let y = positions[i + 1];
        let z = positions[i + 2];

        let x2 = positions[i + 3];
        let y2 = positions[i + 4];
        let z2 = positions[i + 5];

        let x3 = positions[i + 6];
        let y3 = positions[i + 7];
        let z3 = positions[i + 8];

        let skipTriangle = false;

        if (z >= this.clippingSizes.over || 
            z <= this.clippingSizes.under || 
            z2 >= this.clippingSizes.over || 
            z2 <= this.clippingSizes.under || 
            z3 >= this.clippingSizes.over || 
            z3 <= this.clippingSizes.under || 
            y >= this.clippingSizes.rightSide || 
            y <= this.clippingSizes.leftSide || 
            y2 >= this.clippingSizes.rightSide || 
            y2 <= this.clippingSizes.leftSide || 
            y3 >= this.clippingSizes.rightSide || 
            y3 <= this.clippingSizes.leftSide || 
            x <= this.clippingSizes.heel || 
            x >= this.clippingSizes.fingers ||
            x2 <= this.clippingSizes.heel || 
            x2 >= this.clippingSizes.fingers ||
            x3 <= this.clippingSizes.heel || 
            x3 >= this.clippingSizes.fingers) {

            positions[i] = null;
            positions[i + 1] = null;
            positions[i + 2] = null;

            positions[i + 3] = null;
            positions[i + 4] = null;
            positions[i + 5] = null;

            positions[i + 6] = null;
            positions[i + 7] = null;
            positions[i + 8] = null;

            skipTriangle = true;

        }

        if(skipTriangle){
            i += 6
        }

    }

It seems the indices are wrong since your mesh geometry is indexed. That means you also have to reorganize the index buffer.

BTW: You can check whether your geometry has an index or not by checking the index property of your geometry.

I have checked yet, and the index property is null
imagen

I have fixed that, that was totally my fault, I have to increase the index each loop, not only when I found the spcified X, Y or Z.

I just removed the skipTriangle if.

Thanks anyway u’re the man!

2 Likes