Browse Source

Some progress with shape + hole

zz85 14 years ago
parent
commit
41e1ff019b

+ 24 - 19
src/extras/geometries/ExtrudeGeometry.js

@@ -7,11 +7,10 @@ THREE.ExtrudeGeometry = function( shape, options ) {
 
 	var amount = options.amount !== undefined ? options.amount : 100;
 
-	// todo: bezel
-
-	var bezelThickness = options.bezelThickness !== undefined ? options.bezelThickness : 10;
-	var bezelSize = options.bezelSize !== undefined ? options.bezelSize : 8;
-	var bezelEnabled = options.bezelEnabled !== undefined ? options.bezelEnabled : false;
+	// todo: bevel
+	var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 10;
+	var bevelSize = options.bevelSize !== undefined ? options.bevelSize : 8;
+	var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : false;
 
 	var steps = options.steps !== undefined ? options.steps : 1;
 	var extrudePath = options.path !== undefined ? options.path : null;
@@ -30,6 +29,7 @@ THREE.ExtrudeGeometry = function( shape, options ) {
 
 	THREE.Geometry.call( this );
 
+	// getPoints
     var vertices = shape.getSpacedPoints(); // getPoints | getSpacedPoints() you can get variable divisions by dividing by total lenght
 	var reverse = THREE.FontUtils.Triangulate.area( vertices ) > 0 ;
 	if (reverse) {
@@ -41,22 +41,27 @@ THREE.ExtrudeGeometry = function( shape, options ) {
 	
 	var holes =  shape.getHoles();
 	
-	
+	//var faces = THREE.Shape.Utils.triangulateShape(vertices, holes);	
     var faces = THREE.Shape.Utils.triangulate2(vertices, holes);
-	console.log(faces);
+
+
+	//console.log(faces);
 	//var faces = THREE.FontUtils.Triangulate( vertices, true );
 	
+	var contour = vertices; // vertices has all points but contour has only points of circumference
+	
 	var ahole ;
 	for (var h in holes) {
 		ahole = holes[h];
 		vertices = vertices.concat(ahole);
 	}
 	
-    var contour = vertices;
-
-    var scope = this;
-
-	var bezelPoints = [];
+	console.log("same?", contour.length, vertices.length);
+	
+	var scope = this;
+	
+   
+	var bevelPoints = [];
 
 	
 
@@ -65,7 +70,7 @@ THREE.ExtrudeGeometry = function( shape, options ) {
 	var i,
 		vert, vlen = vertices.length,
 		face, flen = faces.length,
-		bezelPt, blen = bezelPoints.length;
+		bevelPt, blen = bevelPoints.length;
 
 	// Back facing vertices
 
@@ -112,19 +117,19 @@ THREE.ExtrudeGeometry = function( shape, options ) {
 	*/
 
 
-	if ( bezelEnabled ) {
+	if ( bevelEnabled ) {
 
 		for ( i = 0; i < blen; i++ ) {
 
-			bezelPt = bezelPoints[ i ];
-			v( bezelPt.x, bezelPt.y, bezelThickness );
+			bevelPt = bevelPoints[ i ];
+			v( bevelPt.x, bevelPt.y, bevelThickness );
 
 		}
 
 		for ( i = 0; i < blen; i++ ) {
 
-			bezelPt = bezelPoints[ i ];
-			v( bezelPt.x, bezelPt.y, amount - bezelThickness );
+			bevelPt = bevelPoints[ i ];
+			v( bevelPt.x, bevelPt.y, amount - bevelThickness );
 
 		}
 
@@ -185,7 +190,7 @@ THREE.ExtrudeGeometry = function( shape, options ) {
 
 		k = i - 1;
 
-		if ( k < 0 ) k = vertices.length - 1;
+		if ( k < 0 ) k = contour.length - 1;
 
 		//console.log('b', i,j, i-1, k,vertices.length);
 

+ 211 - 0
src/extras/geometries/Shape.js

@@ -42,6 +42,217 @@ THREE.Shape.prototype.getHoles = function() {
 
 
 THREE.Shape.Utils = {
+	removeHoles: function(contour, /*array of vector2 for contour*/ 
+							holes /* array of array of vector2 */ ) 
+	{
+		var shape = contour.concat(); // work on this shape
+		var hole;
+		var allpoints = shape.concat();
+		
+		/* For each isolated shape, find the closest points and break to the hole to allow triangulation*/
+		var shortest;
+		
+		var h, h2;
+		
+		
+			var prevShapeVert, nextShapeVert,
+				prevHoleVert, nextHoleVert,
+				holeIndex, shapeIndex,
+				shapeId, shapeGroup,
+				h, h2,
+				hole, shortest, d,
+				p, pts1, pts2,
+				tmpShape1, tmpShape2,
+				tmpHole1, tmpHole2,
+				verts = [];
+		
+		for (h = 0; h < holes.length; h++) {
+			hole = holes[h];
+			/*
+			shapeholes[h].concat(); // preserves original 
+			holes.push(hole);
+			*/
+			allpoints = allpoints.concat(hole);
+			
+			shortest = Number.POSITIVE_INFINITY;
+			
+			
+			// Find the shortest pair of pts between shape and hole
+						
+			// TODO we could optimize with
+			// http://en.wikipedia.org/wiki/Proximity_problems
+			// http://en.wikipedia.org/wiki/Closest_pair_of_points
+			// http://stackoverflow.com/questions/1602164/shortest-distance-between-points-algorithm
+
+			for ( h2 = 0; h2 < hole.length; h2++ ) {
+
+				pts1 = hole[ h2 ];
+
+				for ( p = 0; p < shape.length; p++ ) {
+
+					pts2 = shape[ p ];
+					d = pts1.distanceTo( pts2 );
+
+					if ( d < shortest ) {
+
+						shortest = d;
+						holeIndex = h2;
+						shapeIndex = p;
+
+					}
+
+				}
+
+			}
+
+			prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
+			prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
+			
+			var areaapts = [];
+			areaapts.push( hole[ holeIndex ] );
+			areaapts.push( shape[ shapeIndex ] );
+			areaapts.push( shape[ prevShapeVert ] );
+
+			var areaa = THREE.FontUtils.Triangulate.area( areaapts );
+
+			var areabpts = [];
+			areabpts.push( hole[ holeIndex ] );
+			areabpts.push( hole[ prevHoleVert ] );
+			areabpts.push( shape[ shapeIndex ] );
+
+			var areab = THREE.FontUtils.Triangulate.area( areabpts );
+
+			var shapeOffset = 1;
+			var holeOffset = -1;
+
+			var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
+			shapeIndex += shapeOffset;
+			holeIndex += holeOffset;
+
+			if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
+			shapeIndex %= shape.length;
+
+			if ( holeIndex < 0 ) { holeIndex += hole.length;  }
+			holeIndex %= shape.length;
+
+			prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
+			prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
+			
+			areaapts = [];
+			areaapts.push( hole[ holeIndex ] );
+			areaapts.push( shape[ shapeIndex ] );
+			areaapts.push( shape[ prevShapeVert ] );
+
+			var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );
+
+			areabpts = [];
+			areabpts.push( hole[ holeIndex ] );
+			areabpts.push( hole[ prevHoleVert ] );
+			areabpts.push( shape[ shapeIndex ] );
+
+			var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
+
+			if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {
+				// In case areas are not correct. 
+				
+				shapeIndex = oldShapeIndex;
+				holeIndex = oldHoleIndex ;
+
+				if ( shapeIndex < 0 ) { shapeIndex += shape.length;  }
+				shapeIndex %= shape.length;
+
+				if ( holeIndex < 0 ) { holeIndex += hole.length;  }
+				holeIndex %= shape.length;
+
+				prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
+				prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
+
+			}
+
+			tmpShape1 = shape.slice( 0, shapeIndex );
+			tmpShape2 = shape.slice( shapeIndex );
+			tmpHole1 = hole.slice( holeIndex );
+			tmpHole2 = hole.slice( 0, holeIndex );
+
+			// Should check orders here again?
+			var trianglea =  [
+				hole[ holeIndex ],
+				shape[ shapeIndex ],
+				shape[ prevShapeVert ]
+			];
+							
+			var triangleb = [
+				hole[ holeIndex ] ,
+				hole[ prevHoleVert ],
+				shape[ shapeIndex ]
+			];
+
+			verts.push( trianglea );
+			verts.push( triangleb );
+
+			shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
+			
+		}
+		
+		return {
+			shape:shape, /* shape with no holes */
+			isolatedPts: verts, /* isolated faces */
+			allpoints: allpoints
+		}
+		
+			
+	},
+	
+	triangulateShape: function(contour,holes) {
+		
+		var shapeWithoutHoles = THREE.Shape.Utils.removeHoles(contour,holes);
+		var shape = shapeWithoutHoles.shape,
+			allpoints = shapeWithoutHoles.allpoints,
+			isolatedPts = shapeWithoutHoles.isolatedPts;
+			
+		var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indics for points of spooled shape
+			// to maintain reference to old shape, one must match coords, or offset the indics from original arrays. its probably easier to do the first.
+		//console.log("triangles",triangles, triangles.length);
+		//console.log("allpoints",allpoints, allpoints.length);
+		
+		for ( var v = 0; v < triangles.length; v++ ) {
+
+			var face = triangles[ v ];
+			
+			for (var f=0; f<3; f++) { // For 3 pts in faces
+				for (var i=0; i<allpoints.length;i++) { // Go thru all points
+					
+					if (allpoints[i].equals(face[f])) { // If matches
+						face[f] = i; // face now has reference to index.
+					}
+					
+				}
+				
+				
+			}
+
+		}
+		
+		for ( var v = 0; v < isolatedPts.length; v++ ) {
+			var face = isolatedPts[ v ];
+			
+			for (var f=0; f<3; f++) { // For 3 pts in faces
+				for (var i=0; i<allpoints.length;i++) { // Go thru all points
+					
+					if (allpoints[i].equals(face[f])) { // If matches
+						face[f] = i; // face now has reference to index.
+					}
+					
+				}
+				
+			}
+		}
+		
+		//console.log("edited?" , triangles);
+		return triangles.concat(isolatedPts);
+	
+	}, // end triangulate shapes
+	
 	triangulate2 : function(pts, holes) {
 		// For use Poly2Tri.js 
 	

+ 6 - 0
src/extras/geometries/TextGeometry.js

@@ -1069,9 +1069,15 @@ THREE.FontUtils = {
 
 				/* output Triangle */
 
+				/*
 				result.push( contour[ a ] );
 				result.push( contour[ b ] );
 				result.push( contour[ c ] );
+				*/
+				result.push( [ contour[ a ], 
+					contour[ b ],
+					contour[ c ] ] );
+				
 
 				vertIndices.push( [ verts[ u ], verts[ v ], verts[ w ] ] );