My goal is to extrude faces from a THREE.Geometry object, and my step-by-step approach involves: - Specifying the faces to be extruded - Extracting vertices on the outer edges - Creating a THREE.Shape with these vertices - Extruding the shape using THREE.ExtrudeGeometry (I'm using a customized version that doesn't generate front faces, as I handle cloning them to maintain the original topology).
Initially, the extrusion works well when dealing with a CircleGeometry on an XY plane and extruding in the Z direction. https://i.sstatic.net/p0Ipw.png
However, when I rotate the circle slightly, the extrusion seems to follow the Z World Axes instead of its local orientation. https://i.sstatic.net/zmGmJ.png
I am looking for a solution to this issue. Below is the function I have been using:
function faceExtrude( geometry, face_group, amount ) {
if ( geometry.type === "undefined" ) {
console.log( "faceextrude error" );
return;
}
// Conversion of face_group to vertex_group
var vertex_group = [];
for ( var i = 0; i < face_group.length; i++ ) {
// Retrieve vertices ID
var f = face_group[i];
var a = f.a;
var b = f.b;
var c = f.c;
// Cloning vertices
var v1 = geometry.vertices[a].clone();
var v2 = geometry.vertices[b].clone();
var v3 = geometry.vertices[c].clone();
// Adding them to an array
vertex_group.push(v1, v2, v3);
}
// Side Faces
var vertsToExtrude = [];
// Select only vertices on the outer edge
for ( var v = 0; v < vertex_group.length; v++ ) {
var shareCount = 0;
// Count their presence in each face
for ( var f = 0; f < face_group.length; f++ ) {
if( v == face_group[ f ].a ||
v == face_group[ f ].b ||
v == face_group[ f ].c )
{
shareCount++;
}
}
// Check if less than 4 shares, then it's on an outer edge. Add it to the array
if ( shareCount < 4) {
vertsToExtrude.push( vertex_group[ v ].clone() );
}
}
// Create a shape with selected vertices
var shape = new THREE.Shape();
shape.moveTo( vertsToExtrude[ 0 ].x, vertsToExtrude[ 0 ].y );
for ( var i = 1; i < vertsToExtrude.length; i++ ){
shape.lineTo( vertsToExtrude[ i ].x, vertsToExtrude[ i ].y );
}
shape.lineTo( vertsToExtrude[ 0 ].x, vertsToExtrude[ 0 ].y );
// Extrude the shape
var extrudeSettings = { amount: amount, steps: 2, bevelEnabled: false };
var sideGeo = new THREE.MyExtrudeGeometry( shape, extrudeSettings );
// Front Faces
var frontGeo = new THREE.Geometry();
for ( var i = 0; i < face_group.length; i++ ) {
// Retrieve vertices ID
var f = face_group[i];
var a = f.a;
var b = f.b;
var c = f.c;
// New vertices IDs
var new_a = frontGeo.vertices.length;
var new_b = frontGeo.vertices.length + 1;
var new_c = frontGeo.vertices.length + 2;
// Clone vertices
var v1 = geometry.vertices[a].clone();
var v2 = geometry.vertices[b].clone();
var v3 = geometry.vertices[c].clone();
frontGeo.vertices.push(v1, v2, v3);
// Adjust their z-coordinate based on "amount"
v1.z = v1.z + amount;
v2.z = v2.z + amount;
v3.z = v3.z + amount;
// Add them to a face
var f = new THREE.Face3(new_a, new_b, new_c);
frontGeo.faces.push(f);
}
frontGeo.computeFaceNormals();
geometry.merge( sideGeo );
geometry.merge( frontGeo );
};