Source: Geometry.js

import * as THREE from 'three'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils'

const defaultRadialSegments = 12;
const defaultCapSubdivisions = 2;
const defaultWidthSegments = 12;
const defaultHeightSegments = 6;
const defaultTubularSegments = 12;
const defaultCircularSegments = 32;
const defaultCurveSegments = 12;
const defaultBevelSegments = 8;


var currentFont, currentFontSize, currentFontDepth, currentBevelEnabled, currentBevelThickness, currentBevelSize;

var currentRadialSegments = defaultRadialSegments;
var currentCapSubdivisions = defaultCapSubdivisions;
var currentWidthSegments = defaultWidthSegments;
var currentHeightSegments = defaultHeightSegments
var currentTubularSegments = defaultTubularSegments;
var currentCircularSegments = defaultCircularSegments;
var currentCurveSegments = defaultCurveSegments;
var currentBevelSegments = defaultBevelSegments;

export function setQuality(radialSegments = 1.0, capSubdivisions = 1.0, widthSegments = 1.0, heightSegments = 1.0, tubularSegments = 1.0, circularSegments = 1.0, curveSegments = 1.0, bevelSegments = 1.0) {
  currentRadialSegments = radialSegments * defaultRadialSegments;
  currentCapSubdivisions = capSubdivisions * defaultCapSubdivisions;
  currentWidthSegments = widthSegments * defaultWidthSegments;
  currentHeightSegments = heightSegments * defaultHeightSegments;
  currentTubularSegments = tubularSegments * defaultTubularSegments;
  currentCircularSegments = circularSegments * defaultCircularSegments;
  currentCurveSegments = curveSegments * defaultCurveSegments;
  currentBevelSegments = bevelSegments *  defaultBevelSegments;

}

export function getGeometry(params = {}) {
  var geometry;

  var type = params.type ? params.type : 'box';

  if (type === 'capsule') {
    var radius = params.radius ? params.radius : 0.5;
    var length = params.length ? params.length : 1;
    var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
    var capSubdivisions = params.capSubdivisions ? params.capSubdivisions : currentCapSubdivisions;
    var openEnded = params.openEnded ? params.openEnded : false;

    //CapsuleGeometry(radius : Float, length : Float, capSubdivisions : Integer, radialSegments : Integer)
    geometry = new THREE.CapsuleGeometry(radius, length, capSubdivisions, radialSegments);

  } else if (type === 'ellipsoid') {
    var width = params.width ? params.width : 1;
    var height = params.height ? params.height : 1;
    var depth = params.depth ? params.depth : 1;
    var widthSegments = params.widthSegments ? params.widthSegments : currentWidthSegments;
    var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
    var phiStart = params.phiStart ? params.phiStart : 0;
    var phiLength = params.phiLength ? params.phiLength : Math.PI * 2;
    var thetaStart = params.thetaStart ? params.thetaStart : 0;
    var thetaLength = params.thetaLength ? params.thetaLength : Math.PI;

    // SphereGeometry(radius : Float, widthSegments : Integer, heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float, thetaLength : Float)
    geometry = new THREE.SphereGeometry(0.5, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength);
    geometry.applyMatrix4(new THREE.Matrix4().makeScale(width, height, depth));

  } else if (type === 'plane') {
    var width = params.width ? params.width : 1;
    var height = params.height ? params.height : 1;
    var widthSegments = params.widthSegments ? params.widthSegments : 1;
    var heightSegments = params.heightSegments ? params.heightSegments : 1;
    //PlaneGeometry(width : Float, height : Float, widthSegments : Integer, heightSegments : Integer)
    geometry = new THREE.PlaneGeometry(width, height, widthSegments, heightSegments);

  } else if (type === 'circle') {
    var radius = params.radius ? params.radius : 0.5;
    var segments = params.segments ? params.segments : currentCircularSegments;

    var thetaStart = params.thetaStart ? params.thetaStart : 0;
    var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;
    //CircleGeometry(radius : Float, segments : Integer, thetaStart : Float, thetaLength : Float)
    geometry = new THREE.CircleGeometry(radius, segments, thetaStart, thetaLength);

  } else if (type === 'box') {
    var width = params.width ? params.width : 1;
    var height = params.height ? params.height : 1;
    var depth = params.depth ? params.depth : 1;
    var widthSegments = params.widthSegments ? params.widthSegments : 1;
    var heightSegments = params.heightSegments ? params.heightSegments : 1;
    var depthSegments = params.depthSegments ? params.depthSegments : 1;
    //BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)
    geometry = new THREE.BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments);
  } else if (type === 'cylinder') {
    var radiusTop = params.radiusTop ? params.radiusTop : 0.5;
    var radiusBottom = params.radiusBottom ? params.radiusBottom : 0.5;
    var height = params.height ? params.height : 1;
    var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
    var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
    var openEnded = params.openEnded ? params.openEnded : false;
    var thetaStart = params.thetaStart ? params.thetaStart : 0;
    var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;

    // CylinderGeometry(radiusTop : Float, radiusBottom : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
    geometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
  } else if (type === 'sphere') {
    var radius = params.radius ? params.radius : 0.5;
    var widthSegments = params.widthSegments ? params.widthSegments : currentWidthSegments;
    var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;

    var phiStart = params.phiStart ? params.phiStart : 0;
    var phiLength = params.phiLength ? params.phiLength : Math.PI * 2;
    var thetaStart = params.thetaStart ? params.thetaStart : 0;
    var thetaLength = params.thetaLength ? params.thetaLength : Math.PI;

    // SphereGeometry(radius : Float, widthSegments : Integer, heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float, thetaLength : Float)
    geometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength);
  } else if (type === 'ring') {
    var innerRadius = params.innerRadius ? params.innerRadius : 0.2;
    var outerRadius = params.outerRadius ? params.outerRadius : 0.5;
    var thetaSegments = params.thetaSegments ? params.thetaSegments : 32;
    var phiSegments = params.phiSegments ? params.phiSegments : 12;

    var thetaStart = params.thetaStart ? params.thetaStart : 0;
    var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;

    // RingGeometry(innerRadius : Float, outerRadius : Float, thetaSegments : Integer, phiSegments : Integer, thetaStart : Float, thetaLength : Float)
    geometry = new THREE.RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength);
  } else if (type === 'icosahedron') {
    var radius = params.radius ? params.radius : 0.5;
    var detail = params.detail ? params.detail : 0;

    // IcosahedronGeometry(radius : Float, detail : Integer)
    const originalGeometry = new THREE.IcosahedronGeometry(radius, detail);
    geometry = BufferGeometryUtils.mergeVertices(originalGeometry);
    //geometry = new THREE.IcosahedronGeometry(radius, detail);

  } else if (type === 'octahedron') {
    var radius = params.radius ? params.radius : 0.5;
    var detail = params.detail ? params.detail : 0;
    // OctahedronGeometry(radius : Float, detail : Integer)
    geometry = BufferGeometryUtils.mergeVertices(new THREE.OctahedronGeometry(radius, detail));
  } else if (type === 'tetrahedron') {
    var radius = params.radius ? params.radius : 0.5;
    var detail = params.detail ? params.detail : 0;
    // TetrahedronGeometry(radius : Float, detail : Integer)
    geometry = BufferGeometryUtils.mergeVertices(new THREE.TetrahedronGeometry(radius, detail));
  } else if (type === 'cone') {
    var radius = params.radius ? params.radius : 0.5;
    var height = params.height ? params.height : 1;
    var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
    var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
    var openEnded = params.openEnded ? params.openEnded : false;
    var thetaStart = params.thetaStart ? params.thetaStart : 0;
    var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;

    // ConeGeometry(radius : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
    geometry = new THREE.ConeGeometry(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
  } else if (type === 'torus') {
    var radius = params.radius ? params.radius : 0.5;
    var tube = params.tube ? params.tube : 0.2;
    var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
    var tubularSegments = params.tubularSegments ? params.tubularSegments : currentTubularSegments;
    var arc = params.arc ? params.arc : Math.PI * 2;

    // TorusGeometry(radius : Float, tube : Float, radialSegments : Integer, tubularSegments : Integer, arc : Float)
    geometry = new THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments, arc);
  } else if (type === 'pyramid') {
    var width = params.width ? params.width : 1;
    var height = params.height ? params.height : 1;
    var depth = params.depth ? params.depth : 1;


    const points = [
      new THREE.Vector3(0, height, 0),
      new THREE.Vector3(-width * .5, 0, -depth * .5),
      new THREE.Vector3(-width * .5, 0, depth * .5),
      new THREE.Vector3(width * .5, 0, depth * .5),
      new THREE.Vector3(width * .5, 0, -depth * .5)
    ];
    const vertices = new Float32Array([
      points[0].x, points[0].y, points[0].z,
      points[1].x, points[1].y, points[1].z,
      points[2].x, points[2].y, points[2].z,

      points[0].x, points[0].y, points[0].z,
      points[2].x, points[2].y, points[2].z,
      points[3].x, points[3].y, points[3].z,

      points[0].x, points[0].y, points[0].z,
      points[3].x, points[3].y, points[3].z,
      points[4].x, points[4].y, points[4].z,

      points[0].x, points[0].y, points[0].z,
      points[4].x, points[4].y, points[4].z,
      points[1].x, points[1].y, points[1].z,

      points[1].x, points[1].y, points[1].z,
      points[3].x, points[3].y, points[3].z,
      points[2].x, points[2].y, points[2].z,

      points[1].x, points[1].y, points[1].z,
      points[4].x, points[4].y, points[4].z,
      points[3].x, points[3].y, points[3].z,
    ]);

    geometry = new THREE.BufferGeometry();

    geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
    geometry.computeVertexNormals();

  } else if (type == 'text') {
    if (!currentFont) {
      console.warn("You must use loadFont3D(fontJsonURL) and setFont3D(font) before using text3D()")
      return;
    }
    const text = params.text ? params.text : "?!";
    geometry = new TextGeometry(text, {
      font: currentFont,
      size: currentFontSize,
      height: currentFontDepth,
      bevelEnabled: currentBevelEnabled,
      bevelSize: currentBevelSize,
      bevelThickness: currentBevelThickness,
      curveSegments: currentCurveSegments,
      bevelSegments: currentBevelSegments
    });
    geometry.computeBoundingBox();

    const xMid = - 0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x);
    const yMid = - 0.5 * (geometry.boundingBox.max.y - geometry.boundingBox.min.y);

    geometry.translate(xMid, yMid, 0);
  }
  return geometry;
}
/**
 * 
 * @param {*} font 
 * @param {*} size 
 * @param {*} depth 
 * @param {*} bevelEnabled 
 * @param {*} bevelThickness 
 * @param {*} bevelSize 
 */

export const setFont3D = (font, size = 1, depth = size * 0.5, bevelEnabled = true, bevelThickness = depth * 0.1, bevelSize = bevelThickness) => {
  currentFont = font.font;
  currentFontSize = size;
  currentFontDepth = depth;
  currentBevelEnabled = bevelEnabled;
  currentBevelThickness = bevelThickness;
  currentBevelSize = bevelSize;
}