# BufferGeometry groups to individual BufferGeometries

**URL:** <https://discourse.threejs.org/t/buffergeometry-groups-to-individual-buffergeometries/12812>\
**Category:** Questions\
**Tags:** geometry\
**Created:** [February 17, 2020, 2:09pm UTC](https://discourse.threejs.org/t/buffergeometry-groups-to-individual-buffergeometries/12812 "2020-02-17T14:09:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![peter\_reeves](https://avatars.discourse-cdn.com/v4/letter/p/f08c70/32.png) [@peter\_reeves](https://discourse.threejs.org/u/peter_reeves)\
**Post date:** [February 17, 2020, 2:09pm UTC](https://discourse.threejs.org/t/buffergeometry-groups-to-individual-buffergeometries/12812/1 "2020-02-17T14:09:31Z")

</div>

I’m trying to use the `DRACOExporter` for my project. Occasionally, my project will get a `BufferGeometry` that has “groups” in it. If that is the case, I want to have the `DRACOExporter` export one mesh for every group in the `BufferGeometry`. I’m struggling to find a good way to do this though.

My first thought was to just clone the `BufferGeometry` and manipulate the new copy. Looking at the source code, if I clone a `BufferGeometry`, that will also clone all it’s `BufferAttribute`s, which will all copy their underlying `TypedArray`. I’m hesitant to do this, because some models will have very high poly counts (5 million or more) and I’m worried about how much time/memory that will consume copying the entire array multiple times (If there are 6 groups present, it would copy the same 5 million element array 6 times). However, even if I did just clone the original buffer geometry, I’m not sure how to modify it so that it only has the faces for a single group. Looking at the source code for the `DRACOExporter`, it seems to ignore things like draw ranges anyway?

Is there any way that I can create a `BufferGeometry` which shares the same underlying arrays as another `BufferGeometry`? I see that you can create a new `BufferAttribute` with a `TypedArray`, and I know that `TypedArray`s are views of an underlying `ArrayBuffer`. So I can perhaps create multiple views of the same `ArrayBuffer` and create different `BufferGeometry`s from each one. Once I have multiple `BufferGeometry`s I can then give them one by one to the `DRACOExporter`. I’ve started going down this road, but it’s starting to get a little complicated, and I worry that I might have missed a simpler solution to my problem. Will this strategy (using the same underlying arrays) work, or is there something about three.js that will prevent me from doing this? Alternatively, is there a better solution to my problem?

---

<div class="post-metadata">

**Author:** ![yombo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/yombo/32/3325_2.png) [@yombo](https://discourse.threejs.org/u/yombo)\
**Post date:** [February 17, 2020, 3:31pm UTC](https://discourse.threejs.org/t/buffergeometry-groups-to-individual-buffergeometries/12812/2 "2020-02-17T15:31:44Z")

</div>

I think the best solution in memory and speed is to create new BufferGeometries from the original.

This is for non-indexed geometry. UV coordinates can also be added:

```auto
function separateGroups( bufGeom ) {

	var outGeometries = [];

	var groups = bufGeom.groups;

	var origVerts = bufGeom.getAttribute( 'position' ).array;
	var origNormals = bufGeom.getAttribute( 'normal' ).array;
	var origNumVerts = Math.floor( origVerts.length / 3 );

	for ( var ig = 0, ng = groups.length; ig < ng; ig ++ ) {

		var group = groups[ig];

		var destNumVerts = group.count;

		var newBufGeom = new THREE.BufferGeometry();
		var newPositions = new Float32Array( destNumVerts * 3 );
		var newNormals = new Float32Array( destNumVerts * 3 );

		for ( var iv = 0; iv < destNumVerts; iv ++ ) {

			var indexOrig = 3 * ( group.start + iv );
			var indexDest = 3 * iv;

			newPosition[indexDest] = origVerts[indexOrig];
			newPosition[indexDest + 1] = origVerts[indexOrig + 1];
			newPosition[indexDest + 2] = origVerts[indexOrig + 2];

			newNormals[indexDest] = origNormals[indexOrig];
			newNormals[indexDest + 1] = origNormals[indexOrig + 1];
			newNormals[indexDest + 2] = origNormals[indexOrig + 2];

		}

		newBufGeom.setAttribute( 'position', new Float32BufferAttribute( newPositions, 3 ) );
		newBufGeom.setAttribute( 'normal', new Float32BufferAttribute( newNormals, 3 ) );

		outGeometries.push( newBufGeom );

	}

	return outGeometries;

}

```
