2
0
Эх сурвалжийг харах

Merge pull request #13795 from Mugen87/dev1

ExtrudeGeometry: Refactor interface.
Mr.doob 7 жил өмнө
parent
commit
04e7595c70

+ 0 - 43
docs/api/geometries/ExtrudeBufferGeometry.html

@@ -92,49 +92,6 @@
 			applied to the face; the second material will be applied to the sides.
 		</p>
 
-
-		<h2>Properties</h2>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null addShapeList]([param:Array shapes], [param:Object options])</h3>
-		<p>
-			shapes — An Array of shapes to add. <br />
-			options — Object that can contain the following parameters.
-			<ul>
-				<li>curveSegments — int. Number of points on the curves. Default is 12.</li>
-				<li>steps — int. Number of points used for subdividing segments along the depth of the extruded spline. Default is 1.</li>
-				<li>amount — int. Depth to extrude the shape. Default is 100.</li>
-				<li>bevelEnabled — bool. Apply beveling to the shape. Default is true.</li>
-				<li>bevelThickness — float. How deep into the original shape the bevel goes. Default is 6.</li>
-				<li>bevelSize — float. Distance from the shape outline that the bevel extends. Default is bevelThickness - 2.</li>
-				<li>bevelSegments — int. Number of bevel layers. Default is 3.</li>
-				<li>extrudePath — THREE.CurvePath. A 3D spline path along which the shape should be extruded.</li>
-				<li>UVGenerator —  Object. object that provides UV generator functions</li>
-			</ul>
-		</p>
-		<p>Adds the shapes to the list to extrude.</p>
-
-		<h3>[method:null addShape]([param:Shape shape], [param:Object options])</h3>
-		<p>
-			shape — A shape to add. <br />
-			options — Object that can contain the following parameters.
-			<ul>
-				<li>curveSegments — int. Number of points on the curves. Default is 12.</li>
-				<li>steps — int. Number of points used for subdividing segments along the depth of the extruded spline. Default is 1.</li>
-				<li>amount — int. Depth to extrude the shape. Default is 100.</li>
-				<li>bevelEnabled — bool. Apply beveling to the shape. Default is true.</li>
-				<li>bevelThickness — float. How deep into the original shape the bevel goes. Default is 6.</li>
-				<li>bevelSize — float. Distance from the shape outline that the bevel extends. Default is bevelThickness - 2.</li>
-				<li>bevelSegments — int. Number of bevel layers. Default is 3.</li>
-				<li>extrudePath — THREE.CurvePath. A 3D spline path along which the shape should be extruded.</li>
-				<li>UVGenerator —  Object. object that provides UV generator functions</li>
-			</ul>
-		</p>
-		<p>Add the shape to the list to extrude.</p>
-
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/geometries/ExtrudeGeometry.js src/geometries/ExtrudeGeometry.js]

+ 0 - 43
docs/api/geometries/ExtrudeGeometry.html

@@ -92,49 +92,6 @@
 			applied to the face; the second material will be applied to the sides.
 		</p>
 
-
-		<h2>Properties</h2>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null addShapeList]([param:Array shapes], [param:Object options])</h3>
-		<p>
-			shapes — An Array of shapes to add. <br />
-			options — Object that can contain the following parameters.
-			<ul>
-				<li>curveSegments — int. Number of points on the curves. Default is 12.</li>
-				<li>steps — int. Number of points used for subdividing segments along the depth of the extruded spline. Default is 1.</li>
-				<li>amount — int. Depth to extrude the shape. Default is 100.</li>
-				<li>bevelEnabled — bool. Apply beveling to the shape. Default is true.</li>
-				<li>bevelThickness — float. How deep into the original shape the bevel goes. Default is 6.</li>
-				<li>bevelSize — float. Distance from the shape outline that the bevel extends. Default is bevelThickness - 2.</li>
-				<li>bevelSegments — int. Number of bevel layers. Default is 3.</li>
-				<li>extrudePath — THREE.CurvePath. A 3D spline path along which the shape should be extruded.</li>
-				<li>UVGenerator —  Object. object that provides UV generator functions</li>
-			</ul>
-		</p>
-		<p>Adds the shapes to the list to extrude.</p>
-
-		<h3>[method:null addShape]([param:Shape shape], [param:Object options])</h3>
-		<p>
-			shape — A shape to add. <br />
-			options — Object that can contain the following parameters.
-			<ul>
-				<li>curveSegments — int. Number of points on the curves. Default is 12.</li>
-				<li>steps — int. Number of points used for subdividing segments along the depth of the extruded spline. Default is 1.</li>
-				<li>amount — int. Depth to extrude the shape. Default is 100.</li>
-				<li>bevelEnabled — bool. Apply beveling to the shape. Default is true.</li>
-				<li>bevelThickness — float. How deep into the original shape the bevel goes. Default is 6.</li>
-				<li>bevelSize — float. Distance from the shape outline that the bevel extends. Default is bevelThickness - 2.</li>
-				<li>bevelSegments — int. Number of bevel layers. Default is 3.</li>
-				<li>extrudePath — THREE.CurvePath. A 3D spline path along which the shape should be extruded.</li>
-				<li>UVGenerator —  Object. object that provides UV generator functions</li>
-			</ul>
-		</p>
-		<p>Add the shape to the list to extrude.</p>
-
-
 		<h2>Source</h2>
 
 		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]

+ 25 - 0
src/Three.Legacy.js

@@ -34,6 +34,7 @@ import { SkeletonHelper } from './helpers/SkeletonHelper.js';
 import { BoxGeometry } from './geometries/BoxGeometry.js';
 import { EdgesGeometry } from './geometries/EdgesGeometry.js';
 import { ExtrudeGeometry } from './geometries/ExtrudeGeometry.js';
+import { ExtrudeBufferGeometry } from './geometries/ExtrudeGeometry.js';
 import { ShapeGeometry } from './geometries/ShapeGeometry.js';
 import { WireframeGeometry } from './geometries/WireframeGeometry.js';
 import { Light } from './lights/Light.js';
@@ -1202,6 +1203,30 @@ Object.defineProperties( BufferGeometry.prototype, {
 
 //
 
+Object.assign( ExtrudeBufferGeometry.prototype, {
+
+	getArrays: function () {
+
+		console.error( 'THREE.ExtrudeBufferGeometry: .getArrays() has been removed.' );
+
+	},
+
+	addShapeList: function () {
+
+		console.error( 'THREE.ExtrudeBufferGeometry: .addShapeList() has been removed.' );
+
+	},
+
+	addShape: function () {
+
+		console.error( 'THREE.ExtrudeBufferGeometry: .addShape() has been removed.' );
+
+	}
+
+} );
+
+//
+
 Object.defineProperties( Uniform.prototype, {
 
 	dynamic: {

+ 352 - 380
src/geometries/ExtrudeGeometry.js

@@ -53,479 +53,455 @@ ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;
 
 function ExtrudeBufferGeometry( shapes, options ) {
 
-	if ( typeof ( shapes ) === "undefined" ) {
-
-		return;
-
-	}
-
 	BufferGeometry.call( this );
 
 	this.type = 'ExtrudeBufferGeometry';
 
-	shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
-
-	this.addShapeList( shapes, options );
-
-	this.computeVertexNormals();
-
-}
-
-ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
-ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
-
-ExtrudeBufferGeometry.prototype.getArrays = function () {
-
-	var positionAttribute = this.getAttribute( "position" );
-	var verticesArray = positionAttribute ? Array.prototype.slice.call( positionAttribute.array ) : [];
-
-	var uvAttribute = this.getAttribute( "uv" );
-	var uvArray = uvAttribute ? Array.prototype.slice.call( uvAttribute.array ) : [];
-
-	return {
-		position: verticesArray,
-		uv: uvArray
+	this.parameters = {
+		shapes: shapes,
+		options: options
 	};
 
-};
+	shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
 
-ExtrudeBufferGeometry.prototype.addShapeList = function ( shapes, options ) {
+	var scope = this;
 
-	var sl = shapes.length;
-	options.arrays = this.getArrays();
+	var verticesArray = [];
+	var uvArray = [];
 
-	for ( var s = 0; s < sl; s ++ ) {
+	for ( var i = 0, l = shapes.length; i < l; i ++ ) {
 
-		var shape = shapes[ s ];
-		this.addShape( shape, options );
+		var shape = shapes[ i ];
+		addShape( shape, options );
 
 	}
 
-	this.addAttribute( 'position', new Float32BufferAttribute( options.arrays.position, 3 ) );
-	this.addAttribute( 'uv', new Float32BufferAttribute( options.arrays.uv, 2 ) );
+	// build geometry
 
-};
+	this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
+	this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
 
-ExtrudeBufferGeometry.prototype.addShape = function ( shape, options ) {
+	this.computeVertexNormals();
 
-	var arrays = options.arrays ? options.arrays : this.getArrays();
-	var verticesArray = arrays.position;
-	var uvArray = arrays.uv;
+	// functions
 
-	var placeholder = [];
+	function addShape( shape ) {
 
+		var placeholder = [];
 
-	var amount = options.amount !== undefined ? options.amount : 100;
+		// options
 
-	var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10
-	var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
-	var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
+		var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
+		var steps = options.steps !== undefined ? options.steps : 1;
+		var amount = options.amount !== undefined ? options.amount : 100;
 
-	var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
+		var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
+		var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
+		var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2;
+		var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
 
-	var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
+		var extrudePath = options.extrudePath;
 
-	var steps = options.steps !== undefined ? options.steps : 1;
+		var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;
 
-	var extrudePath = options.extrudePath;
-	var extrudePts, extrudeByPath = false;
+		//
 
-	// Use default WorldUVGenerator if no UV generators are specified.
-	var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : ExtrudeGeometry.WorldUVGenerator;
+		var extrudePts, extrudeByPath = false;
+		var splineTube, binormal, normal, position2;
 
-	var splineTube, binormal, normal, position2;
-	if ( extrudePath ) {
+		if ( extrudePath ) {
 
-		extrudePts = extrudePath.getSpacedPoints( steps );
+			extrudePts = extrudePath.getSpacedPoints( steps );
 
-		extrudeByPath = true;
-		bevelEnabled = false; // bevels not supported for path extrusion
+			extrudeByPath = true;
+			bevelEnabled = false; // bevels not supported for path extrusion
 
-		// SETUP TNB variables
+			// SETUP TNB variables
 
-		// TODO1 - have a .isClosed in spline?
+			// TODO1 - have a .isClosed in spline?
 
-		splineTube = extrudePath.computeFrenetFrames( steps, false );
+			splineTube = extrudePath.computeFrenetFrames( steps, false );
 
-		// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
+			// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
 
-		binormal = new Vector3();
-		normal = new Vector3();
-		position2 = new Vector3();
+			binormal = new Vector3();
+			normal = new Vector3();
+			position2 = new Vector3();
 
-	}
+		}
 
-	// Safeguards if bevels are not enabled
+		// Safeguards if bevels are not enabled
 
-	if ( ! bevelEnabled ) {
+		if ( ! bevelEnabled ) {
 
-		bevelSegments = 0;
-		bevelThickness = 0;
-		bevelSize = 0;
+			bevelSegments = 0;
+			bevelThickness = 0;
+			bevelSize = 0;
 
-	}
+		}
 
-	// Variables initialization
+		// Variables initialization
 
-	var ahole, h, hl; // looping of holes
-	var scope = this;
+		var ahole, h, hl; // looping of holes
 
-	var shapePoints = shape.extractPoints( curveSegments );
+		var shapePoints = shape.extractPoints( curveSegments );
 
-	var vertices = shapePoints.shape;
-	var holes = shapePoints.holes;
+		var vertices = shapePoints.shape;
+		var holes = shapePoints.holes;
 
-	var reverse = ! ShapeUtils.isClockWise( vertices );
+		var reverse = ! ShapeUtils.isClockWise( vertices );
 
-	if ( reverse ) {
+		if ( reverse ) {
 
-		vertices = vertices.reverse();
+			vertices = vertices.reverse();
 
-		// Maybe we should also check if holes are in the opposite direction, just to be safe ...
+			// Maybe we should also check if holes are in the opposite direction, just to be safe ...
 
-		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
+			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
 
-			ahole = holes[ h ];
+				ahole = holes[ h ];
 
-			if ( ShapeUtils.isClockWise( ahole ) ) {
+				if ( ShapeUtils.isClockWise( ahole ) ) {
 
-				holes[ h ] = ahole.reverse();
+					holes[ h ] = ahole.reverse();
+
+				}
 
 			}
 
 		}
 
-	}
 
+		var faces = ShapeUtils.triangulateShape( vertices, holes );
 
-	var faces = ShapeUtils.triangulateShape( vertices, holes );
+		/* Vertices */
 
-	/* Vertices */
+		var contour = vertices; // vertices has all points but contour has only points of circumference
 
-	var contour = vertices; // vertices has all points but contour has only points of circumference
+		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
 
-	for ( h = 0, hl = holes.length; h < hl; h ++ ) {
+			ahole = holes[ h ];
 
-		ahole = holes[ h ];
+			vertices = vertices.concat( ahole );
 
-		vertices = vertices.concat( ahole );
+		}
 
-	}
 
+		function scalePt2( pt, vec, size ) {
 
-	function scalePt2( pt, vec, size ) {
+			if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
 
-		if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
+			return vec.clone().multiplyScalar( size ).add( pt );
 
-		return vec.clone().multiplyScalar( size ).add( pt );
+		}
 
-	}
+		var b, bs, t, z,
+			vert, vlen = vertices.length,
+			face, flen = faces.length;
 
-	var b, bs, t, z,
-		vert, vlen = vertices.length,
-		face, flen = faces.length;
 
+		// Find directions for point movement
 
-	// Find directions for point movement
 
+		function getBevelVec( inPt, inPrev, inNext ) {
 
-	function getBevelVec( inPt, inPrev, inNext ) {
+			// computes for inPt the corresponding point inPt' on a new contour
+			//   shifted by 1 unit (length of normalized vector) to the left
+			// if we walk along contour clockwise, this new contour is outside the old one
+			//
+			// inPt' is the intersection of the two lines parallel to the two
+			//  adjacent edges of inPt at a distance of 1 unit on the left side.
 
-		// computes for inPt the corresponding point inPt' on a new contour
-		//   shifted by 1 unit (length of normalized vector) to the left
-		// if we walk along contour clockwise, this new contour is outside the old one
-		//
-		// inPt' is the intersection of the two lines parallel to the two
-		//  adjacent edges of inPt at a distance of 1 unit on the left side.
+			var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
 
-		var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
+			// good reading for geometry algorithms (here: line-line intersection)
+			// http://geomalgorithms.com/a05-_intersect-1.html
 
-		// good reading for geometry algorithms (here: line-line intersection)
-		// http://geomalgorithms.com/a05-_intersect-1.html
+			var v_prev_x = inPt.x - inPrev.x,
+				v_prev_y = inPt.y - inPrev.y;
+			var v_next_x = inNext.x - inPt.x,
+				v_next_y = inNext.y - inPt.y;
 
-		var v_prev_x = inPt.x - inPrev.x,
-			v_prev_y = inPt.y - inPrev.y;
-		var v_next_x = inNext.x - inPt.x,
-			v_next_y = inNext.y - inPt.y;
+			var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
 
-		var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
+			// check for collinear edges
+			var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
 
-		// check for collinear edges
-		var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
+			if ( Math.abs( collinear0 ) > Number.EPSILON ) {
 
-		if ( Math.abs( collinear0 ) > Number.EPSILON ) {
+				// not collinear
 
-			// not collinear
+				// length of vectors for normalizing
 
-			// length of vectors for normalizing
+				var v_prev_len = Math.sqrt( v_prev_lensq );
+				var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
 
-			var v_prev_len = Math.sqrt( v_prev_lensq );
-			var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
+				// shift adjacent points by unit vectors to the left
 
-			// shift adjacent points by unit vectors to the left
+				var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
+				var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
 
-			var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
-			var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
+				var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
+				var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
 
-			var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
-			var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
+				// scaling factor for v_prev to intersection point
 
-			// scaling factor for v_prev to intersection point
+				var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
+						( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
+					( v_prev_x * v_next_y - v_prev_y * v_next_x );
 
-			var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
-					( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
-				( v_prev_x * v_next_y - v_prev_y * v_next_x );
+				// vector from inPt to intersection point
 
-			// vector from inPt to intersection point
+				v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
+				v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
 
-			v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
-			v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
+				// Don't normalize!, otherwise sharp corners become ugly
+				//  but prevent crazy spikes
+				var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
+				if ( v_trans_lensq <= 2 ) {
 
-			// Don't normalize!, otherwise sharp corners become ugly
-			//  but prevent crazy spikes
-			var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
-			if ( v_trans_lensq <= 2 ) {
+					return new Vector2( v_trans_x, v_trans_y );
 
-				return new Vector2( v_trans_x, v_trans_y );
+				} else {
 
-			} else {
+					shrink_by = Math.sqrt( v_trans_lensq / 2 );
 
-				shrink_by = Math.sqrt( v_trans_lensq / 2 );
+				}
 
-			}
+			} else {
 
-		} else {
+				// handle special case of collinear edges
 
-			// handle special case of collinear edges
+				var direction_eq = false; // assumes: opposite
+				if ( v_prev_x > Number.EPSILON ) {
 
-			var direction_eq = false; // assumes: opposite
-			if ( v_prev_x > Number.EPSILON ) {
+					if ( v_next_x > Number.EPSILON ) {
 
-				if ( v_next_x > Number.EPSILON ) {
+						direction_eq = true;
 
-					direction_eq = true;
+					}
 
-				}
+				} else {
 
-			} else {
+					if ( v_prev_x < - Number.EPSILON ) {
 
-				if ( v_prev_x < - Number.EPSILON ) {
+						if ( v_next_x < - Number.EPSILON ) {
 
-					if ( v_next_x < - Number.EPSILON ) {
+							direction_eq = true;
 
-						direction_eq = true;
+						}
 
-					}
+					} else {
 
-				} else {
+						if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
 
-					if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
+							direction_eq = true;
 
-						direction_eq = true;
+						}
 
 					}
 
 				}
 
-			}
+				if ( direction_eq ) {
 
-			if ( direction_eq ) {
+					// console.log("Warning: lines are a straight sequence");
+					v_trans_x = - v_prev_y;
+					v_trans_y = v_prev_x;
+					shrink_by = Math.sqrt( v_prev_lensq );
 
-				// console.log("Warning: lines are a straight sequence");
-				v_trans_x = - v_prev_y;
-				v_trans_y = v_prev_x;
-				shrink_by = Math.sqrt( v_prev_lensq );
+				} else {
 
-			} else {
+					// console.log("Warning: lines are a straight spike");
+					v_trans_x = v_prev_x;
+					v_trans_y = v_prev_y;
+					shrink_by = Math.sqrt( v_prev_lensq / 2 );
 
-				// console.log("Warning: lines are a straight spike");
-				v_trans_x = v_prev_x;
-				v_trans_y = v_prev_y;
-				shrink_by = Math.sqrt( v_prev_lensq / 2 );
+				}
 
 			}
 
+			return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
+
 		}
 
-		return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );
 
-	}
+		var contourMovements = [];
 
+		for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
 
-	var contourMovements = [];
+			if ( j === il ) j = 0;
+			if ( k === il ) k = 0;
 
-	for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
+			//  (j)---(i)---(k)
+			// console.log('i,j,k', i, j , k)
 
-		if ( j === il ) j = 0;
-		if ( k === il ) k = 0;
+			contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
 
-		//  (j)---(i)---(k)
-		// console.log('i,j,k', i, j , k)
+		}
 
-		contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
+		var holesMovements = [],
+			oneHoleMovements, verticesMovements = contourMovements.concat();
 
-	}
+		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
 
-	var holesMovements = [],
-		oneHoleMovements, verticesMovements = contourMovements.concat();
+			ahole = holes[ h ];
 
-	for ( h = 0, hl = holes.length; h < hl; h ++ ) {
+			oneHoleMovements = [];
 
-		ahole = holes[ h ];
+			for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
 
-		oneHoleMovements = [];
+				if ( j === il ) j = 0;
+				if ( k === il ) k = 0;
 
-		for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
+				//  (j)---(i)---(k)
+				oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
 
-			if ( j === il ) j = 0;
-			if ( k === il ) k = 0;
+			}
 
-			//  (j)---(i)---(k)
-			oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
+			holesMovements.push( oneHoleMovements );
+			verticesMovements = verticesMovements.concat( oneHoleMovements );
 
 		}
 
-		holesMovements.push( oneHoleMovements );
-		verticesMovements = verticesMovements.concat( oneHoleMovements );
 
-	}
+		// Loop bevelSegments, 1 for the front, 1 for the back
 
+		for ( b = 0; b < bevelSegments; b ++ ) {
 
-	// Loop bevelSegments, 1 for the front, 1 for the back
+			//for ( b = bevelSegments; b > 0; b -- ) {
 
-	for ( b = 0; b < bevelSegments; b ++ ) {
+			t = b / bevelSegments;
+			z = bevelThickness * Math.cos( t * Math.PI / 2 );
+			bs = bevelSize * Math.sin( t * Math.PI / 2 );
 
-		//for ( b = bevelSegments; b > 0; b -- ) {
+			// contract shape
 
-		t = b / bevelSegments;
-		z = bevelThickness * Math.cos( t * Math.PI / 2 );
-		bs = bevelSize * Math.sin( t * Math.PI / 2 );
+			for ( i = 0, il = contour.length; i < il; i ++ ) {
 
-		// contract shape
+				vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
 
-		for ( i = 0, il = contour.length; i < il; i ++ ) {
-
-			vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
+				v( vert.x, vert.y, - z );
 
-			v( vert.x, vert.y, - z );
+			}
 
-		}
+			// expand holes
 
-		// expand holes
+			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
 
-		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
+				ahole = holes[ h ];
+				oneHoleMovements = holesMovements[ h ];
 
-			ahole = holes[ h ];
-			oneHoleMovements = holesMovements[ h ];
+				for ( i = 0, il = ahole.length; i < il; i ++ ) {
 
-			for ( i = 0, il = ahole.length; i < il; i ++ ) {
+					vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
 
-				vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
+					v( vert.x, vert.y, - z );
 
-				v( vert.x, vert.y, - z );
+				}
 
 			}
 
 		}
 
-	}
+		bs = bevelSize;
 
-	bs = bevelSize;
+		// Back facing vertices
 
-	// Back facing vertices
+		for ( i = 0; i < vlen; i ++ ) {
 
-	for ( i = 0; i < vlen; i ++ ) {
+			vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
 
-		vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
+			if ( ! extrudeByPath ) {
 
-		if ( ! extrudeByPath ) {
+				v( vert.x, vert.y, 0 );
 
-			v( vert.x, vert.y, 0 );
+			} else {
 
-		} else {
+				// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
 
-			// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
+				normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
+				binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
 
-			normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
-			binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
+				position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
 
-			position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
+				v( position2.x, position2.y, position2.z );
 
-			v( position2.x, position2.y, position2.z );
+			}
 
 		}
 
-	}
+		// Add stepped vertices...
+		// Including front facing vertices
 
-	// Add stepped vertices...
-	// Including front facing vertices
+		var s;
 
-	var s;
+		for ( s = 1; s <= steps; s ++ ) {
 
-	for ( s = 1; s <= steps; s ++ ) {
+			for ( i = 0; i < vlen; i ++ ) {
 
-		for ( i = 0; i < vlen; i ++ ) {
+				vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
 
-			vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
+				if ( ! extrudeByPath ) {
 
-			if ( ! extrudeByPath ) {
+					v( vert.x, vert.y, amount / steps * s );
 
-				v( vert.x, vert.y, amount / steps * s );
+				} else {
 
-			} else {
+					// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
 
-				// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
+					normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
+					binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
 
-				normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
-				binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
+					position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
 
-				position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
+					v( position2.x, position2.y, position2.z );
 
-				v( position2.x, position2.y, position2.z );
+				}
 
 			}
 
 		}
 
-	}
 
+		// Add bevel segments planes
 
-	// Add bevel segments planes
+		//for ( b = 1; b <= bevelSegments; b ++ ) {
+		for ( b = bevelSegments - 1; b >= 0; b -- ) {
 
-	//for ( b = 1; b <= bevelSegments; b ++ ) {
-	for ( b = bevelSegments - 1; b >= 0; b -- ) {
+			t = b / bevelSegments;
+			z = bevelThickness * Math.cos( t * Math.PI / 2 );
+			bs = bevelSize * Math.sin( t * Math.PI / 2 );
 
-		t = b / bevelSegments;
-		z = bevelThickness * Math.cos( t * Math.PI / 2 );
-		bs = bevelSize * Math.sin( t * Math.PI / 2 );
+			// contract shape
 
-		// contract shape
+			for ( i = 0, il = contour.length; i < il; i ++ ) {
 
-		for ( i = 0, il = contour.length; i < il; i ++ ) {
+				vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
+				v( vert.x, vert.y, amount + z );
 
-			vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
-			v( vert.x, vert.y, amount + z );
+			}
 
-		}
+			// expand holes
 
-		// expand holes
+			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
 
-		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
+				ahole = holes[ h ];
+				oneHoleMovements = holesMovements[ h ];
 
-			ahole = holes[ h ];
-			oneHoleMovements = holesMovements[ h ];
+				for ( i = 0, il = ahole.length; i < il; i ++ ) {
 
-			for ( i = 0, il = ahole.length; i < il; i ++ ) {
+					vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
 
-				vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
+					if ( ! extrudeByPath ) {
 
-				if ( ! extrudeByPath ) {
+						v( vert.x, vert.y, amount + z );
 
-					v( vert.x, vert.y, amount + z );
+					} else {
 
-				} else {
+						v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
 
-					v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
+					}
 
 				}
 
@@ -533,210 +509,206 @@ ExtrudeBufferGeometry.prototype.addShape = function ( shape, options ) {
 
 		}
 
-	}
+		/* Faces */
 
-	/* Faces */
+		// Top and bottom faces
 
-	// Top and bottom faces
+		buildLidFaces();
 
-	buildLidFaces();
+		// Sides faces
 
-	// Sides faces
+		buildSideFaces();
 
-	buildSideFaces();
 
+		/////  Internal functions
 
-	/////  Internal functions
+		function buildLidFaces() {
 
-	function buildLidFaces() {
+			var start = verticesArray.length / 3;
 
-		var start = verticesArray.length / 3;
+			if ( bevelEnabled ) {
 
-		if ( bevelEnabled ) {
+				var layer = 0; // steps + 1
+				var offset = vlen * layer;
 
-			var layer = 0; // steps + 1
-			var offset = vlen * layer;
+				// Bottom faces
 
-			// Bottom faces
+				for ( i = 0; i < flen; i ++ ) {
 
-			for ( i = 0; i < flen; i ++ ) {
+					face = faces[ i ];
+					f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
 
-				face = faces[ i ];
-				f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
+				}
 
-			}
+				layer = steps + bevelSegments * 2;
+				offset = vlen * layer;
 
-			layer = steps + bevelSegments * 2;
-			offset = vlen * layer;
+				// Top faces
 
-			// Top faces
+				for ( i = 0; i < flen; i ++ ) {
 
-			for ( i = 0; i < flen; i ++ ) {
+					face = faces[ i ];
+					f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
 
-				face = faces[ i ];
-				f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
+				}
 
-			}
+			} else {
 
-		} else {
+				// Bottom faces
 
-			// Bottom faces
+				for ( i = 0; i < flen; i ++ ) {
 
-			for ( i = 0; i < flen; i ++ ) {
+					face = faces[ i ];
+					f3( face[ 2 ], face[ 1 ], face[ 0 ] );
 
-				face = faces[ i ];
-				f3( face[ 2 ], face[ 1 ], face[ 0 ] );
+				}
 
-			}
+				// Top faces
 
-			// Top faces
+				for ( i = 0; i < flen; i ++ ) {
 
-			for ( i = 0; i < flen; i ++ ) {
+					face = faces[ i ];
+					f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
 
-				face = faces[ i ];
-				f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
+				}
 
 			}
 
+			scope.addGroup( start, verticesArray.length / 3 - start, 0 );
+
 		}
 
-		scope.addGroup( start, verticesArray.length / 3 - start, 0 );
+		// Create faces for the z-sides of the shape
 
-	}
+		function buildSideFaces() {
 
-	// Create faces for the z-sides of the shape
+			var start = verticesArray.length / 3;
+			var layeroffset = 0;
+			sidewalls( contour, layeroffset );
+			layeroffset += contour.length;
 
-	function buildSideFaces() {
+			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
 
-		var start = verticesArray.length / 3;
-		var layeroffset = 0;
-		sidewalls( contour, layeroffset );
-		layeroffset += contour.length;
+				ahole = holes[ h ];
+				sidewalls( ahole, layeroffset );
 
-		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
-
-			ahole = holes[ h ];
-			sidewalls( ahole, layeroffset );
+				//, true
+				layeroffset += ahole.length;
 
-			//, true
-			layeroffset += ahole.length;
+			}
 
-		}
 
+			scope.addGroup( start, verticesArray.length / 3 - start, 1 );
 
-		scope.addGroup( start, verticesArray.length / 3 - start, 1 );
 
+		}
 
-	}
+		function sidewalls( contour, layeroffset ) {
 
-	function sidewalls( contour, layeroffset ) {
+			var j, k;
+			i = contour.length;
 
-		var j, k;
-		i = contour.length;
+			while ( -- i >= 0 ) {
 
-		while ( -- i >= 0 ) {
+				j = i;
+				k = i - 1;
+				if ( k < 0 ) k = contour.length - 1;
 
-			j = i;
-			k = i - 1;
-			if ( k < 0 ) k = contour.length - 1;
+				//console.log('b', i,j, i-1, k,vertices.length);
 
-			//console.log('b', i,j, i-1, k,vertices.length);
+				var s = 0,
+					sl = steps + bevelSegments * 2;
 
-			var s = 0,
-				sl = steps + bevelSegments * 2;
+				for ( s = 0; s < sl; s ++ ) {
 
-			for ( s = 0; s < sl; s ++ ) {
+					var slen1 = vlen * s;
+					var slen2 = vlen * ( s + 1 );
 
-				var slen1 = vlen * s;
-				var slen2 = vlen * ( s + 1 );
+					var a = layeroffset + j + slen1,
+						b = layeroffset + k + slen1,
+						c = layeroffset + k + slen2,
+						d = layeroffset + j + slen2;
 
-				var a = layeroffset + j + slen1,
-					b = layeroffset + k + slen1,
-					c = layeroffset + k + slen2,
-					d = layeroffset + j + slen2;
+					f4( a, b, c, d );
 
-				f4( a, b, c, d );
+				}
 
 			}
 
 		}
 
-	}
+		function v( x, y, z ) {
 
-	function v( x, y, z ) {
+			placeholder.push( x );
+			placeholder.push( y );
+			placeholder.push( z );
 
-		placeholder.push( x );
-		placeholder.push( y );
-		placeholder.push( z );
+		}
 
-	}
 
+		function f3( a, b, c ) {
 
-	function f3( a, b, c ) {
+			addVertex( a );
+			addVertex( b );
+			addVertex( c );
 
-		addVertex( a );
-		addVertex( b );
-		addVertex( c );
+			var nextIndex = verticesArray.length / 3;
+			var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
 
-		var nextIndex = verticesArray.length / 3;
-		var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
+			addUV( uvs[ 0 ] );
+			addUV( uvs[ 1 ] );
+			addUV( uvs[ 2 ] );
 
-		addUV( uvs[ 0 ] );
-		addUV( uvs[ 1 ] );
-		addUV( uvs[ 2 ] );
+		}
 
-	}
+		function f4( a, b, c, d ) {
 
-	function f4( a, b, c, d ) {
+			addVertex( a );
+			addVertex( b );
+			addVertex( d );
 
-		addVertex( a );
-		addVertex( b );
-		addVertex( d );
+			addVertex( b );
+			addVertex( c );
+			addVertex( d );
 
-		addVertex( b );
-		addVertex( c );
-		addVertex( d );
 
+			var nextIndex = verticesArray.length / 3;
+			var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
 
-		var nextIndex = verticesArray.length / 3;
-		var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
+			addUV( uvs[ 0 ] );
+			addUV( uvs[ 1 ] );
+			addUV( uvs[ 3 ] );
 
-		addUV( uvs[ 0 ] );
-		addUV( uvs[ 1 ] );
-		addUV( uvs[ 3 ] );
+			addUV( uvs[ 1 ] );
+			addUV( uvs[ 2 ] );
+			addUV( uvs[ 3 ] );
 
-		addUV( uvs[ 1 ] );
-		addUV( uvs[ 2 ] );
-		addUV( uvs[ 3 ] );
+		}
 
-	}
+		function addVertex( index ) {
 
-	function addVertex( index ) {
+			verticesArray.push( placeholder[ index * 3 + 0 ] );
+			verticesArray.push( placeholder[ index * 3 + 1 ] );
+			verticesArray.push( placeholder[ index * 3 + 2 ] );
 
-		verticesArray.push( placeholder[ index * 3 + 0 ] );
-		verticesArray.push( placeholder[ index * 3 + 1 ] );
-		verticesArray.push( placeholder[ index * 3 + 2 ] );
+		}
 
-	}
 
+		function addUV( vector2 ) {
 
-	function addUV( vector2 ) {
+			uvArray.push( vector2.x );
+			uvArray.push( vector2.y );
 
-		uvArray.push( vector2.x );
-		uvArray.push( vector2.y );
+		}
 
 	}
 
-	if ( ! options.arrays ) {
-
-		this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
-		this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
-
-	}
+}
 
-};
+ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
+ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
 
-ExtrudeGeometry.WorldUVGenerator = {
+var WorldUVGenerator = {
 
 	generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {