In my self-made geometries I sometimes calculate all or only certain normals myself.
Example from the Collection of examples from discourse.threejs.org
from line 735
g.computeVertexNormals( );
if ( connected ) { // calculate new normals at mantle seam
for( let i = 0; i <= g.vertical; i ++ ) {
smoothEdge( ( g.radial + 1 ) * i, ( g.radial + 1 ) * i + g.radial );
}
}
if ( wTop && !flatTop ) { // calculate new normals at top seam
for( let j = 0; j <= g.radial; j ++ ) {
smoothEdge( ( g.radial + 1 ) * ( g.vertical + 1 ) + 1 + j, j );
}
}
if ( wBtm && !flatBtm ) { // calculate new normals at bottom seam
for( let j = 0; j <= g.radial ; j ++ ) {
const offs = wTop ? + g.radial + 2 : 0;
smoothEdge( ( g.radial + 1 ) * g.vertical + j, ( g.radial + 1 ) * ( g.vertical + 1 ) + offs + 1 + j );
}
}
g.attributes.normal.needsUpdate = true;