docs: function(data) {
      if (!data) return null;
      var geoset = [];
      var self = this;
  
      function applyNoise(geo, noise) {
        var n = new THREE.Vector3();
        for (var i = 0, numVerts = geo.vertices.length; i < numVerts; i++) {
          n.x = (self.random(i) - 0.5) * noise;
          n.y = (self.random(i + numVerts) - 0.5) * noise;
          n.z = (self.random(i + numVerts * 2) - 0.5) * noise;
          geo.vertices[i].add(n);
        }
      }
  
      var i, geo, verts;
  
      for (var j = 0; j < data.length; j++) {
  
        if (data[j].type == 'lathe') {
          var maxy = -99999;
          var points = [];
          verts = data[j].vertices;
          for (i = 0; i < verts.length; i += 2) {
            points.push(new THREE.Vector2(verts[i], verts[i + 1]));
            if (verts[i + 1] > maxy) {
              maxy = verts[i + 1];
            }
          }
          geo = new THREE.LatheGeometry(points, data[j]['segments'] || 8);
          geo.applyMatrix(new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(-Math.PI, 0, 0)));
          geo.applyMatrix(new THREE.Matrix4().makeTranslation(0, maxy, 0));
          if (data[j]['noise']) applyNoise(geo, data[j].noise);
          geoset.push(geo);
        }
  
        else if (data[j].type == 'extrude') {
          var shape = new THREE.Shape();
          verts = data[j].vertices;
          for (i = 0; i < verts.length; i+= 2) {
            if (i == 0) shape.moveTo(verts[i], verts[i + 1]);
            else shape.lineTo(verts[i], verts[i + 1]);
          }
          geo = new THREE.ExtrudeGeometry(shape, {amount: 1, bevelEnabled: false});
          geo.applyMatrix(new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0)));
          if (data[j]['noise']) applyNoise(geo, data[j].noise);
          geoset.push(geo);
        }
  
        else if (data[j].type == 'mesh') {
          geo = new THREE.Geometry();
          verts = data[j].vertices;
          var faces = data[j].faces;
          for (var v = 0; v < verts.length; v += 3) {
            geo.vertices.push(new THREE.Vector3(verts[v], verts[v + 1], verts[v + 2]));
          }
          for (var f = 0; f < faces.length; f += 3) {
            geo.faces.push(new THREE.Face3(faces[f], faces[f + 1], faces[f + 2]));
          }
          if (this.data.flatShading || data[j]['flatShading']) {
            geo.computeFaceNormals();
          }
          else {
            geo.computeVertexNormals();
          }
  
          if (data[j]['mirror']) {
            geo.merge(geo, new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(0, Math.PI, 0)));
          }
  
          if (data[j]['noise']) applyNoise(geo, data[j].noise);
          geoset.push(geo);
        }
      }
      return geoset;
    }