# Pick and extract triangle from given Mesh

In general the problem explained - I want to pick a triangle from out a given mesh (can be sphere, octahedron or custom loaded mesh). When picked, I want to extract this triangle and build one new triangle from out of it - where I´m able to even give it a texture.

Maybe this have been already done (pretty sure) and someone can point me in the correct direction?

Thanks
B

I’ve lately shared some code that colors a face on click. You can use the raycasting code as a basis for you own project.

Instead of updating the color buffer attribute, you extract the vertices from the position attribute with the given indices. These vertices can then be used to build your new triangle.

1 Like

Thanks @Mugen87 ,

I seem to have hit/intersect something and console.log the info, it tells me:

1. distance: 109.82558899335417
2. face: Face3 {a: 162, b: 163, c: 164, normal: Vector3, vertexNormals: Array(0), …}
3. faceIndex: 54
4. object: Mesh {uuid: “344334D9-65F0-43A8-9F38-C96173C853F3”, name: “test”, type: “Mesh”, parent: Scene, children: Array(0), …}
5. point: Vector3 {x: 74.8670946633202, y: -14.35672669571743, z: -28.925857437901616, isVector3: true}
6. uv: Vector2 {x: 0.5415250916781218, y: 0.31839238562267214, isVector2: true}

The question is - how do I now get the xyz/vertex info of the triangle I have hit?
Sry for being so lost here…

Don´t mind - I think I found some:

var vA = new THREE.Vector3();
var vB = new THREE.Vector3();
var vC = new THREE.Vector3();

var face = intersection.face;
var geometry = intersection.object.geometry;
var position = geometry.attributes.position;

vA.fromBufferAttribute( position, face.a );
vB.fromBufferAttribute( position, face.b );
vC.fromBufferAttribute( position, face.c );
1 Like

But, if I now want to build a new triangle from this and put in a texture (use a material) as well, how would I achieve this @Mugen87 @prisoner849 ?

For texture, you need UV coords on those points.
Use the same a, b, c properties of face to retreive information from uv attribute for respective vertices.

One question: If the mesh I hit a triangle from is scaled and rotated, who can I apply same rotation and scale to the “extracted” triangle as well so that it fits 1:1

Don´t mind me - mesh.rotation and scale (xyz) === origin hitted triangle rotation and scale

So I would:

const uvs = intersect[0].object.geometry.getAttribute(‘uv’);
var uvX = new THREE.Vector2();

uvX.fromBufferAttribute( uvs, face.a)

Here is what I have so far - but still no texture appearing in my triangle:

const positions = intersect[0].object.geometry.getAttribute(‘position’);
const uvs = intersect[0].object.geometry.getAttribute(‘uv’);
const face = intersect[0].face;

var vA = new THREE.Vector3();
var vB = new THREE.Vector3();
var vC = new THREE.Vector3();

vA.fromBufferAttribute( positions, face.a );
vB.fromBufferAttribute( positions, face.b );
vC.fromBufferAttribute( positions, face.c );

var uv1 = new THREE.Vector2();
var uv2 = new THREE.Vector2();
var uv3 = new THREE.Vector2();

uv1.fromBufferAttribute( uvs, face.a );
uv2.fromBufferAttribute( uvs, face.b );
uv3.fromBufferAttribute( uvs, face.c );

let mesh = new THREE.BufferGeometry();
const vertices = new Float32Array([vA.x, vA.y, vA.z, vB.x, vB.y, vB.z, vC.x, vC.y, vC.z]);

mesh.setAttribute(
‘position’,
new THREE.BufferAttribute(vertices, 3).setUsage(THREE.DynamicDrawUsage)
);

const uvs_ = new Float32Array([uv1.x, uv1.y, uv2.x, uv2.y, uv3.x, uv3.y]);
mesh.setAttribute(
‘uv’,
new THREE.BufferAttribute(uvs, 2).setUsage(THREE.DynamicDrawUsage)
);

var mesh1 = new THREE.Mesh(mesh, new THREE.MeshBasicMaterial( { map:texture}) );
1 Like

Yes - but the triangle still is not textured when applying a map to it?

@blackInk
Any chance to provide an editable working example, that demonstrates the issue?

It was my bad - it did work actually - but I had the material´s opacity set to 0, so I tricked myself when saying the texture is not there - it worked fine! Thanks @prisoner849 @Mugen87

1 Like