Threejs - Shape Components + Attachment

by black strings

HTML

<script src="https://rawgit.com/mrdoob/three.js/dev/build/three.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js"></script>

JavaScript

'use strict';
class Utils {
	static point2dsToVec2s(point2ds){
  	const vec2s = [];
  	point2ds.forEach( (point2d) => {
    	vec2s.push(new THREE.Vector2(point2d[0], point2d[1]));
    });	
    return vec2s;
  }
  static point2dsToVec3s(point3ds){
  	const vec3s = [];
  	point3ds.forEach( (point3d) => {
    	vec3s.push(new THREE.Vector3(point3d[0], point3d[1], 0));
    });	
    return vec3s;
  }
  static vec3sToVec2s(vec3s){
  	const vec2s = [];
  	vec3s.forEach( (v3) => {
    	vec2s.push(new THREE.Vector2(v3.x, v3.y));
    });	
    return vec2s;
  }
  static createGeometryFrom2dArray(point2ds){
    const vec2s = [];
    for (const point of point2ds) {
      vec2s.push(new THREE.Vector2(point[0], point[1]));
    }
    const threeShape = new THREE.Shape(vec2s);
    const threeShapeGeometry = new THREE.ShapeGeometry(threeShape);
    return threeShapeGeometry;
  }
  static getCenter(v1, v2) {
    let center = null;
    if (v1 && v2) {
      center = new THREE.Vector3();
      center.x = (v1.x + v2.x) / 2;
      center.y = (v1.y + v2.y) / 2;
      center.z = (v1.z + v2.z) / 2;
    } else {
      console.log(`One (or both) of the vectors is null or undefined`);
    }
    return center;
  }
  static create2dFromVec3s(vec3s, color){
  	if(!vec3s) { console.warn('no vec3s');}
    if(!color) { console.warn('no color'); }
  	var vec2s = Utils.vec3sToVec2s(vec3s);
  	const shape = new THREE.Shape(vec2s);
    const geo = new THREE.ShapeGeometry(shape);
    const mat = new THREE.MeshBasicMaterial({color: color});
  	const mesh = new THREE.Mesh(geo, mat);
    return mesh;
  }
  static createSideGeometry(v1,v2) {
  	const innerGap = 6;
    const outerGap = 1;
    const thickness = 3;
    // get the clone vertices of start and end of the line
    // avoid using the actual vertices
    const p1 = v1.clone();
    const p2 = v2.clone();
    
    const dir = new THREE.Vector3();
    const sideLength = p1.distanceTo(p2);
    const grabSpotLength = sideLength - innerGap * 2;

    //...