Texture for the object gets overlapped when it is loaded again

Hi i am having an issue when i try to load an obj file.

First time when the object is being loaded it doesnt have an issue, it gives proper object in the 3d scene.
But next time when i load it the png files seems to be overlapping.
And this issue is not there, when i reload the 3d scene and then again object is loaded.
It seems like previous buffer for texture is somehow still there.

Whenever i try to reload the object,
The geometry, material and material.map all are disposed.
Is it something to do material.map not being removed.

before

This is the obj file when i load it for first time.

after
This is the obj file on the second loading.

Here is my code snippet to load object.

loadOBJ(type) {
      try {
        this.loadOBJECT.children[0]
        .material.map.dispose()
        this.loadOBJECT.children[0]
          .material.dispose()
        this.loadOBJECT.children[0]
          .geometry.dispose()
        this.scene.remove(
          this.scene.getObjectByProperty('uuid', this.loadOBJUuid)
        )
      } catch (error) {
        console.log(error)
      }
      let self = this
      var mtlLoader = new THREE.MTLLoader()
      mtlLoader.load(this.URL + 'static/data/' + type + '_mesh.mtl', function(
        materials
      ) {
        materials.preload()
        var objLoader = new THREE.OBJLoader()
        objLoader.setMaterials(materials)
        objLoader.load(self.URL + 'static/data/' + type + '_mesh.obj', function(
          object
        ) {
          var mesh = object
          var texture = new THREE.TextureLoader().load(
            self.URL + 'static/data/' + type + '_mesh_0.png'
          )
          self.scene.add(mesh)
          self.loadOBJECT = mesh
          console.log(mesh);
          self.loadOBJUuid = mesh.uuid
    /*       setTimeout(() => {
              if (mesh.children[0].material.map != null)
                mesh.children[0].material.map.dispose()
              mesh.children[0]
              .material.map = texture
              self.scene.add(mesh)
              self.loadOBJECT = mesh
              console.log(mesh);
              self.loadOBJUuid = mesh.uuid
          }, 5000); */
        })
    })
}

And i have delete function which does the same first 4 lines in function above, which disposes the obj.

    deleteOBJ() {
      try {
        this.loadOBJECT.children[0]
        .material.map.dispose()
        this.loadOBJECT.children[0]
          .material.dispose()
        this.loadOBJECT.children[0]
          .geometry.dispose()
        this.scene.remove(
          this.scene.getObjectByProperty('uuid', this.loadOBJUuid)
        )
      } catch (error) {
        console.log(error)
      }
    }

Please help.

  1. Consider using glTF / glb file format. Obj is obsolete and annoying to work with.
  2. Your deleteOBJ function is not correct - if object has no material, dispose will throw an exception - which then leads to (1) object geometry not being disposed at all, (2) object not being removed from the scene.
  3. Judging by point (2.2) - try adding the following line at the beginning of the deleteOBJ:
this.loadOBJECT.children[0].position.add(new THREE.Vector3().random());

If that fixes the issue (or you simply see two objects), it means your previous object was never removed and is currently z-fighting a newly loaded one.

  1. Instead of using try / catch change them to if conditionals. Your code right now is a bit unpredictable.
1 Like

Like mjurczyk said i changed the try catch to if conditions which checks if the geometry and materials are undefined.

but the overlapping of texture was cause i dint do mesh.children.material.map.needsUpdate = true( png file which i used as the texture was always updating - which i forgot to mention).

 
        objLoader.load(this.URL + 'static/data/' + type + '_mesh.obj', function(
          object
        ) {
          var mesh = object
          var texture = new THREE.TextureLoader().load(
            this.URL + 'static/data/' + type + '_mesh_0.png'
          )

          mesh.traverse(function(child) {
            if (child instanceof THREE.Mesh) {
              child.material.map = texture
              child.material.map.needsUpdate = true // this fixed it
            }
          })
          self.scene.add(mesh)
          self.loadOBJUuid = mesh.uuid
        })