Pārlūkot izejas kodu

PLYLoader: Ignore lines in the body (#25796)

* PLYLoader: Ignore lines in the body

Instead of assuming that each line describes one object,
simply split the body at whitespaces and consume the
resulting token stream with no regard to line boundaries.

This is needed because, for example, some ply files exported
by librealsense use multiple lines to describe a single object[0].

[0]: https://github.com/IntelRealSense/librealsense/blob/e9f05c55f88f6876633bd59fd1cb3848da64b699/include/librealsense2/hpp/rs_export.hpp#L240

Co-authored-by: Michael Herzog <[email protected]>

* Update PLYLoader.js

---------

Co-authored-by: Michael Herzog <[email protected]>
Barnabás Pőcze 2 gadi atpakaļ
vecāks
revīzija
324904d17e
1 mainītis faili ar 47 papildinājumiem un 34 dzēšanām
  1. 47 34
      examples/jsm/loaders/PLYLoader.js

+ 47 - 34
examples/jsm/loaders/PLYLoader.js

@@ -243,22 +243,24 @@ class PLYLoader extends Loader {
 
 		}
 
-		function parseASCIIElement( properties, line ) {
-
-			const values = line.split( /\s+/ );
+		function parseASCIIElement( properties, tokens ) {
 
 			const element = {};
 
 			for ( let i = 0; i < properties.length; i ++ ) {
 
+				if ( tokens.empty() ) return null;
+
 				if ( properties[ i ].type === 'list' ) {
 
 					const list = [];
-					const n = parseASCIINumber( values.shift(), properties[ i ].countType );
+					const n = parseASCIINumber( tokens.next(), properties[ i ].countType );
 
 					for ( let j = 0; j < n; j ++ ) {
 
-						list.push( parseASCIINumber( values.shift(), properties[ i ].itemType ) );
+						if ( tokens.empty() ) return null;
+
+						list.push( parseASCIINumber( tokens.next(), properties[ i ].itemType ) );
 
 					}
 
@@ -266,7 +268,7 @@ class PLYLoader extends Loader {
 
 				} else {
 
-					element[ properties[ i ].name ] = parseASCIINumber( values.shift(), properties[ i ].type );
+					element[ properties[ i ].name ] = parseASCIINumber( tokens.next(), properties[ i ].type );
 
 				}
 
@@ -341,47 +343,35 @@ class PLYLoader extends Loader {
 
 			const buffer = createBuffer();
 
-			let result;
-
-			const patternBody = /end_header\s([\s\S]*)$/;
-			let body = '';
-			if ( ( result = patternBody.exec( data ) ) !== null ) {
+			const patternBody = /end_header\s+(\S[\s\S]*\S|\S)\s*$/;
+			let body, matches;
 
-				body = result[ 1 ];
+			if ( ( matches = patternBody.exec( data ) ) !== null ) {
 
-			}
+				body = matches[ 1 ].split( /\s+/ );
 
-			const lines = body.split( /\r\n|\r|\n/ );
-			let currentElement = 0;
-			let currentElementCount = 0;
-			let elementDesc = header.elements[ currentElement ];
-			let attributeMap = mapElementAttributes( elementDesc.properties );
+			} else {
 
-			for ( let i = 0; i < lines.length; i ++ ) {
+				body = [ ];
 
-				let line = lines[ i ];
-				line = line.trim();
-				if ( line === '' ) {
+			}
 
-					continue;
+			const tokens = new ArrayStream( body );
 
-				}
+			loop: for ( let i = 0; i < header.elements.length; i ++ ) {
 
-				if ( currentElementCount >= elementDesc.count ) {
+				const elementDesc = header.elements[ i ];
+				const attributeMap = mapElementAttributes( elementDesc.properties );
 
-					currentElement ++;
-					currentElementCount = 0;
-					elementDesc = header.elements[ currentElement ];
+				for ( let j = 0; j < elementDesc.count; j ++ ) {
 
-					attributeMap = mapElementAttributes( elementDesc.properties );
+					const element = parseASCIIElement( elementDesc.properties, tokens );
 
-				}
+					if ( ! element ) break loop;
 
-				const element = parseASCIIElement( elementDesc.properties, line );
-
-				handleElement( buffer, elementDesc.name, element, attributeMap );
+					handleElement( buffer, elementDesc.name, element, attributeMap );
 
-				currentElementCount ++;
+				}
 
 			}
 
@@ -733,4 +723,27 @@ class PLYLoader extends Loader {
 
 }
 
+class ArrayStream {
+
+	constructor( arr ) {
+
+		this.arr = arr;
+		this.i = 0;
+
+	}
+
+	empty() {
+
+		return this.i >= this.arr.length;
+
+	}
+
+	next() {
+
+		return this.arr[ this.i ++ ];
+
+	}
+
+}
+
 export { PLYLoader };