BufferGeometry uv generating doesn't work


I started working with a library called IFC.js which is a library that helps visualize IFC files (architectural 3D models).
This library works with BufferGeometry without uv - because these files doesn’t have this information.
So I found an algorithm that should calculate the uv automatically so I can put textures on objects.
The problem is that the texture loading on the object looks exactly the same before and after this algorithm - it looks like one color and not like the image.
I tried to set the uv values randomly just to see a change, but nothing changes.
Here is my code - its very ugly because i just wanted it to work:

function assignUVs(geometry: BufferGeometry) {

    const positionsArray = geometry.getAttribute('position').array;
    const normalsArray = geometry.getAttribute('normal').array;
    const vertices = [];
    const normals = [];

    for (let i = 0; i < positionsArray.length; i=i+3){
        vertices.push(new THREE.Vector3(positionsArray[i], positionsArray[i+1], positionsArray[i+2]));
        normals.push(new THREE.Vector3(normalsArray[i], normalsArray[i+1], normalsArray[i+2]));

    const uvs = new Float32Array(vertices.length * 2);
    let uvsIdx = 0;

    const indices = geometry.index?.array || [];
    for (let i = 0; i < indices.length; i=i+3){

      const normal = new THREE.Vector3().crossVectors(
        new THREE.Vector3().subVectors(normals[indices[i+1]], normals[indices[i]]),
        new THREE.Vector3().subVectors(normals[indices[i+2]], normals[indices[i]])

      const face = {
        a: vertices[indices[i]],
        b: vertices[indices[i+1]],
        c: vertices[indices[i+2]],
      var components = ['x', 'y', 'z'].sort(function(a, b) {
          return Math.abs((face.normal as any)[a]) > Math.abs((face.normal as any)[b]) ? 1 : 0;

      var v1 = face.a;
      var v2 = face.b;
      var v3 = face.c;

      uvs[uvsIdx] = (v1 as any)[components[0]];
      uvs[uvsIdx+1] = (v1 as any)[components[1]];
      uvs[uvsIdx+2] = (v2 as any)[components[0]];
      uvs[uvsIdx+3] = (v2 as any)[components[1]];
      uvs[uvsIdx+4] = (v3 as any)[components[0]];
      uvs[uvsIdx+5] = (v3 as any)[components[1]];
      uvsIdx = uvsIdx + 6;
    const attr = new THREE.BufferAttribute(uvs, 2);
    attr.needsUpdate = true;
    geometry.setAttribute('uv', attr);

and this is the code outside of this function:

const floorTexture = new THREE.TextureLoader().load( '../../textures/door3.jpg' );
const floorMaterial = new THREE.MeshBasicMaterial( { map: floorTexture } );
subset.material = floorMaterial;

Does anyone has any idea?
Thanks a lot!

Check what is uv array was before applying uv and after applying uv

1 Like

There wasn’t uv before, I’m trying to create it from scratch. but the point is that whatever values inside, it looks exactly the same, as the new uv array doesn’t effect anything at all.

Cant test code into chrome console. Unexpected identifier “any”.
Maybe you can upload example to Codepen, fiddle, sandbox

return Math.abs((face.normal as any)[a]) > Math.abs((face.normal