Changing the geometry of a mesh

I use a combined class for Mesh and SkinnedMesh, to attach or detach a skeleton or to reuse it from an object pool without dumping every old and spawning new meshes.

While it works assigning another geometry, i wonder if i have to delete references somewhere (mesh-geometry relation lookups maybe), or if it’s memoryleak-free. I just found older posts around this topic, maybe this isn’t even a issue anymore.

1 Like

Because geometries get cached inside the renderer, you should always call geometry.dispose() if you delete/free an instance of Geometry or BufferGeometry.

https://threejs.org/examples/webgl_geometry_extrude_splines.html is a good example for this.

3 Likes

But the geometries aren’t deleted at this time, just changed to another, it’s not a generated only used once. Or does it free kinda references i mentioned?

Can you post your code? I’m sure this will help to clarify the situation :wink:

1 Like

Basically when a asset is assigned it just sets the geometry property of the mesh, when i replace the asset (for example to customize a character), i assign the geometry and call a method which does THREE.Mesh or THREE.SkinnedMesh constructor specific things, that’s all.

Now my concerns are that there are for example mesh.uuid+geometry.uuid stored references in the renderer or properties that will be stored for skeleton animations, since the mesh object won’t be dropped, but use a different geometry.

I think you’re not understanding the answer or we don’t understand the question without code. Geometry basically ends up being stored in two places. In your main memory once you construct say a BufferGeometry and fill it with data, and on the GPU, once the WebGLRenderer.render() encounters a node in the scene graph for the first time using that geometry. If you don’t call dispose, this will remain forever on the GPU.

1 Like

My question is anwerd thanks, i digged through the renderer and there aren’t such references i expected.

If we remove a Mesh from a scene graph, then create a new Mesh and do mesh.geometry = theSameGeometryAsBefore on this new Mesh so that the new Mesh has the same geometry instance as the previous Mesh, do we need to call dispose() on the geometry?

If there isn’t anything in the renderer that associates geometry with meshes, then the answer will be that we don’t (i.e. if dispose() is only for clearing the GPU of the geometry data, then it makes sense we don’t need to dispose, and that the geometry will be transformed based on whichever mesh it is encountered on, and that any number of meshes can use the same geometry instance).

Just looking for confirmation. Thanks!

@trusktr You should really works on making your posts short and clear. I get lost halfway through…

I guess his question is similar to the one i asked. If there are references or anything stored in the relation of mesh with geometry, like for caching purposes.

@mrdoob I mean, is the following okay?

const geometry = new SphereGeometry

let mesh = new Mesh
mesh.geometry = geometry

// then later:

mesh = new Mesh
mesh.geometry = geometry

Is not calling geometry.dispose() before assigning the geometry to a new Mesh okay?

Is not calling geometry.dispose() before assigning the geometry to a new Mesh okay?

No, is not ok.

1 Like

Then, @anon13924900, you do need to call dispose().

@mrdoob Why does .dispose() need to be called when assigning a geometry to another Mesh?

EDIT: I looked at WebGLGeometries#onGeometryDispose and I only see that it removes the Geometry from the WebGLGeometries list, and removes gl attributes. I’m not yet seeing why .dispose() is needed when assigning a Geometry to another Mesh.

Because the WebGLRenderer uploads that geometry to the GPU. You need to notify the system, somehow, that you don’t need that geometry on the GPU anymore.

1 Like

But we still need the Geometry on the GPU because we assigned it to another mesh, I thought.

f.e.

const geometryToMove = mesh1.geometry
scene.remove(mesh1)

var mesh2 = new Mesh
mesh2.geometry = geometryToMove
scene.add(mesh2)

renderer.render(scene, camera)

In that example, we’re just moving the Geometry, so it will still be used by the GPU. We don’t need to dispose() in that case?

You don’t need to do dispose() in that case, nop.

1 Like