Browse Source

Speed up regex execution by removing unused group captures from ^f lines.
Handle null (\0) terminated files. At least one (LeePerrySmith.obj) in the three.js repo was throwing exception because of this. Afaik this was not introduced by me, probably this file is not used in any example atm.
Throw exception also when v/f prefixed line cannot be parsed. This preserves behavior with the pre refactoring code.

Jonne Nauha 9 năm trước cách đây
mục cha
commit
dce794ddb1
1 tập tin đã thay đổi với 36 bổ sung15 xóa
  1. 36 15
      examples/js/loaders/OBJLoader.js

+ 36 - 15
examples/js/loaders/OBJLoader.js

@@ -18,11 +18,11 @@ THREE.OBJLoader = function ( manager ) {
 		// f vertex vertex vertex
 		face_vertex              : /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/,
 		// f vertex/uv vertex/uv vertex/uv
-		face_vertex_uv           : /^f\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)))?/,
+		face_vertex_uv           : /^f\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+))?/,
 		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal
-		face_vertex_uv_normal    : /^f\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)\/(-?\d+)))?/,
+		face_vertex_uv_normal    : /^f\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)\s+(-?\d+)\/(-?\d+)\/(-?\d+)(?:\s+(-?\d+)\/(-?\d+)\/(-?\d+))?/,
 		// f vertex//normal vertex//normal vertex//normal
-		face_vertex_normal       : /^f\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))(?:\s+((-?\d+)\/\/(-?\d+)))?/,
+		face_vertex_normal       : /^f\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)\s+(-?\d+)\/\/(-?\d+)(?:\s+(-?\d+)\/\/(-?\d+))?/,
 		// o object_name | g group_name
 		object_pattern           : /^[og]\s*(.+)?/,
 		// s boolean
@@ -259,7 +259,8 @@ THREE.OBJLoader.prototype = {
 			else
 				line = line.trim();
 
-			if ( line.length === 0 ) {
+			var lineLength = line.length;
+			if ( lineLength === 0 ) {
 				continue;
 			}
 
@@ -276,6 +277,7 @@ THREE.OBJLoader.prototype = {
 
 				if ( lineSecondChar === " " && ( result = this.regexp.vertex_pattern.exec( line ) ) !== null ) {
 
+					// 0                  1      2      3
 					// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
 
 					state.vertices.push(
@@ -286,6 +288,7 @@ THREE.OBJLoader.prototype = {
 
 				} else if ( lineSecondChar === "n" && ( result = this.regexp.normal_pattern.exec( line ) ) !== null ) {
 
+					// 0                   1      2      3
 					// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
 
 					state.normals.push(
@@ -296,6 +299,7 @@ THREE.OBJLoader.prototype = {
 
 				} else if ( lineSecondChar === "t" && ( result = this.regexp.uv_pattern.exec( line ) ) !== null ) {
 
+					// 0               1      2
 					// ["vt 0.1 0.2", "0.1", "0.2"]
 
 					state.uvs.push(
@@ -303,50 +307,63 @@ THREE.OBJLoader.prototype = {
 						parseFloat( result[ 2 ] )
 					);
 
+				} else {
+
+					throw new Error( "Unexpected vertex/normal/uv line: '" + line  + "'");
+
 				}
+
 			} else if ( lineFirstChar === "f" ) {
 
 				if ( ( result = this.regexp.face_vertex_uv_normal.exec( line ) ) !== null ) {
 
 					// f vertex/uv/normal vertex/uv/normal vertex/uv/normal
-					// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
+					// 0                        1    2    3    4    5    6    7    8    9   10         11         12
+					// ["f 1/1/1 2/2/2 3/3/3", "1", "1", "1", "2", "2", "2", "3", "3", "3", undefined, undefined, undefined]
 
 					state.addFace(
-						result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ],
-						result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ],
-						result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ]
+						result[ 1 ], result[ 4 ], result[ 7 ], result[ 10 ],
+						result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
+						result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
 					);
 
 				} else if ( ( result = this.regexp.face_vertex_uv.exec( line ) ) !== null ) {
 
 					// f vertex/uv vertex/uv vertex/uv
-					// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
+					// 0                  1    2    3    4    5    6   7          8
+					// ["f 1/1 2/2 3/3", "1", "1", "2", "2", "3", "3", undefined, undefined]
 
 					state.addFace(
-						result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
-						result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
+						result[ 1 ], result[ 3 ], result[ 5 ], result[ 7 ],
+						result[ 2 ], result[ 4 ], result[ 6 ], result[ 8 ]
 					);
 
 				} else if ( ( result = this.regexp.face_vertex_normal.exec( line ) ) !== null ) {
 
 					// f vertex//normal vertex//normal vertex//normal
-					// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
+					// 0                     1    2    3    4    5    6   7          8
+					// ["f 1//1 2//2 3//3", "1", "1", "2", "2", "3", "3", undefined, undefined]
 
 					state.addFace(
-						result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
+						result[ 1 ], result[ 3 ], result[ 5 ], result[ 7 ],
 						undefined, undefined, undefined, undefined,
-						result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
+						result[ 2 ], result[ 4 ], result[ 6 ], result[ 8 ]
 					);
 
 				} else if ( ( result = this.regexp.face_vertex.exec( line ) ) !== null ) {
 
 					// f vertex vertex vertex
+					// 0            1    2    3   4
 					// ["f 1 2 3", "1", "2", "3", undefined]
 
 					state.addFace(
 						result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ]
 					);
 
+				} else {
+
+					throw new Error( "Unexpected face line: '" + line  + "'");
+
 				}
 
 			} else if ( ( result = this.regexp.object_pattern.exec( line ) ) !== null ) {
@@ -379,7 +396,11 @@ THREE.OBJLoader.prototype = {
 
 			} else {
 
-				throw new Error( "Unexpected line: " + line );
+				// Handle null terminated files without exception
+				if (line === "\0")
+					continue;
+
+				throw new Error( "Unexpected line: '" + line  + "'");
 
 			}