Browse Source

Editor: Added ifc files support (#21551)

* WebIFC: Load wasm from same path.

* IFCLoader: Use async/await to make sure the wasm is loaded at parse time.

* Editor: Added ifc files support.

* Editor: Added IFCLoader to sw.js
Mr.doob 4 years ago
parent
commit
afccc97c23
4 changed files with 101 additions and 79 deletions
  1. 17 0
      editor/js/Loader.js
  2. 3 0
      editor/sw.js
  3. 79 78
      examples/jsm/loaders/IFCLoader.js
  4. 2 1
      examples/jsm/loaders/ifc/web-ifc-api.js

+ 17 - 0
editor/js/Loader.js

@@ -347,6 +347,23 @@ function Loader( editor ) {
 
 				break;
 
+			case 'ifc':
+
+				reader.addEventListener( 'load', async function ( event ) {
+
+					var { IFCLoader } = await import( '../../examples/jsm/loaders/IFCLoader.js' );
+
+					var loader = new IFCLoader();
+					var scene = await loader.parse( event.target.result );
+
+					scene.name = filename;
+
+					editor.execute( new AddObjectCommand( editor, scene ) );
+
+				}, false );
+				reader.readAsArrayBuffer( file );
+
+				break;
 
 			case 'kmz':
 

+ 3 - 0
editor/sw.js

@@ -37,6 +37,9 @@ const assets = [
 	'../examples/jsm/loaders/FBXLoader.js',
 	'../examples/jsm/loaders/GLTFLoader.js',
 	'../examples/jsm/loaders/KMZLoader.js',
+	'../examples/jsm/loaders/IFCLoader.js',
+	'../examples/jsm/loaders/ifc/web-ifc-api.js',
+	'../examples/jsm/loaders/ifc/web-ifc.wasm',
 	'../examples/jsm/loaders/MD2Loader.js',
 	'../examples/jsm/loaders/OBJLoader.js',
 	'../examples/jsm/loaders/MTLLoader.js',

+ 79 - 78
examples/jsm/loaders/IFCLoader.js

@@ -17,7 +17,6 @@ import {
 } from '../../../../build/three.module.js';
 
 var ifcAPI = new IfcAPI();
-ifcAPI.Init();
 
 function IFCLoader( manager ) {
 
@@ -40,11 +39,11 @@ IFCLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 		loader.setWithCredentials( scope.withCredentials );
 		loader.load(
 			url,
-			function ( buffer ) {
+			async function ( buffer ) {
 
 				try {
 
-					onLoad( scope.parse( buffer ) );
+					onLoad( await scope.parse( buffer ) );
 
 				} catch ( e ) {
 
@@ -69,108 +68,110 @@ IFCLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 	},
 
-	parse: ( function () {
+	parse: async function ( buffer ) {
 
-		return function ( buffer ) {
+		if ( ifcAPI.wasmModule === undefined ) {
 
-			var data = new Uint8Array( buffer );
-			var modelID = ifcAPI.OpenModel( 'example.ifc', data );
-			return loadAllGeometry( modelID );
+			await ifcAPI.Init();
 
-			function loadAllGeometry( modelID ) {
+		}
 
-				var flatMeshes = getFlatMeshes( modelID );
-				var mainObject = new Object3D();
-				for ( var i = 0; i < flatMeshes.size(); i ++ ) {
+		var data = new Uint8Array( buffer );
+		var modelID = ifcAPI.OpenModel( 'example.ifc', data );
+		return loadAllGeometry( modelID );
 
-					var placedGeometries = flatMeshes.get( i ).geometries;
-					for ( var j = 0; j < placedGeometries.size(); j ++ )
-						mainObject.add( getPlacedGeometry( modelID, placedGeometries.get( j ) ) );
+		function loadAllGeometry( modelID ) {
 
-				}
+			var flatMeshes = getFlatMeshes( modelID );
+			var mainObject = new Object3D();
+			for ( var i = 0; i < flatMeshes.size(); i ++ ) {
 
-				return mainObject;
+				var placedGeometries = flatMeshes.get( i ).geometries;
+				for ( var j = 0; j < placedGeometries.size(); j ++ )
+					mainObject.add( getPlacedGeometry( modelID, placedGeometries.get( j ) ) );
 
 			}
 
-			function getFlatMeshes( modelID ) {
+			return mainObject;
 
-				var flatMeshes = ifcAPI.LoadAllGeometry( modelID );
-				return flatMeshes;
+		}
 
-			}
+		function getFlatMeshes( modelID ) {
 
-			function getPlacedGeometry( modelID, placedGeometry ) {
+			var flatMeshes = ifcAPI.LoadAllGeometry( modelID );
+			return flatMeshes;
 
-				var geometry = getBufferGeometry( modelID, placedGeometry );
-				var material = getMeshMaterial( placedGeometry.color );
-				var mesh = new Mesh( geometry, material );
-				mesh.matrix = getMeshMatrix( placedGeometry.flatTransformation );
-				mesh.matrixAutoUpdate = false;
-				return mesh;
+		}
 
-			}
+		function getPlacedGeometry( modelID, placedGeometry ) {
 
-			function getBufferGeometry( modelID, placedGeometry ) {
-
-				var geometry = ifcAPI.GetGeometry(
-					modelID,
-					placedGeometry.geometryExpressID
-				);
-				var verts = ifcAPI.GetVertexArray(
-					geometry.GetVertexData(),
-					geometry.GetVertexDataSize()
-				);
-				var indices = ifcAPI.GetIndexArray(
-					geometry.GetIndexData(),
-					geometry.GetIndexDataSize()
-				);
-				var bufferGeometry = ifcGeometryToBuffer( verts, indices );
-				return bufferGeometry;
+			var geometry = getBufferGeometry( modelID, placedGeometry );
+			var material = getMeshMaterial( placedGeometry.color );
+			var mesh = new Mesh( geometry, material );
+			mesh.matrix = getMeshMatrix( placedGeometry.flatTransformation );
+			mesh.matrixAutoUpdate = false;
+			return mesh;
 
-			}
+		}
 
-			function getMeshMaterial( color ) {
+		function getBufferGeometry( modelID, placedGeometry ) {
 
-				var col = new Color( color.x, color.y, color.z );
-				var material = new MeshPhongMaterial( { color: col, side: DoubleSide } );
-				material.transparent = color.w !== 1;
-				if ( material.transparent ) material.opacity = color.w;
-				return material;
+			var geometry = ifcAPI.GetGeometry(
+				modelID,
+				placedGeometry.geometryExpressID
+			);
+			var verts = ifcAPI.GetVertexArray(
+				geometry.GetVertexData(),
+				geometry.GetVertexDataSize()
+			);
+			var indices = ifcAPI.GetIndexArray(
+				geometry.GetIndexData(),
+				geometry.GetIndexDataSize()
+			);
+			var bufferGeometry = ifcGeometryToBuffer( verts, indices );
+			return bufferGeometry;
 
-			}
+		}
 
-			function getMeshMatrix( matrix ) {
+		function getMeshMaterial( color ) {
 
-				var mat = new Matrix4();
-				mat.fromArray( matrix );
-				// mat.elements[15 - 3] *= 0.001;
-				// mat.elements[15 - 2] *= 0.001;
-				// mat.elements[15 - 1] *= 0.001;
-				return mat;
+			var col = new Color( color.x, color.y, color.z );
+			var material = new MeshPhongMaterial( { color: col, side: DoubleSide } );
+			material.transparent = color.w !== 1;
+			if ( material.transparent ) material.opacity = color.w;
+			return material;
 
-			}
+		}
 
-			function ifcGeometryToBuffer( vertexData, indexData ) {
-
-				var geometry = new BufferGeometry();
-				var buffer32 = new InterleavedBuffer( vertexData, 6 );
-				geometry.setAttribute(
-					'position',
-					new InterleavedBufferAttribute( buffer32, 3, 0 )
-				);
-				geometry.setAttribute(
-					'normal',
-					new InterleavedBufferAttribute( buffer32, 3, 3 )
-				);
-				geometry.setIndex( new BufferAttribute( indexData, 1 ) );
-				return geometry;
+		function getMeshMatrix( matrix ) {
 
-			}
+			var mat = new Matrix4();
+			mat.fromArray( matrix );
+			// mat.elements[15 - 3] *= 0.001;
+			// mat.elements[15 - 2] *= 0.001;
+			// mat.elements[15 - 1] *= 0.001;
+			return mat;
+
+		}
+
+		function ifcGeometryToBuffer( vertexData, indexData ) {
+
+			var geometry = new BufferGeometry();
+			var buffer32 = new InterleavedBuffer( vertexData, 6 );
+			geometry.setAttribute(
+				'position',
+				new InterleavedBufferAttribute( buffer32, 3, 0 )
+			);
+			geometry.setAttribute(
+				'normal',
+				new InterleavedBufferAttribute( buffer32, 3, 3 )
+			);
+			geometry.setIndex( new BufferAttribute( indexData, 1 ) );
+			return geometry;
 
-		};
+		}
 
-	} )(),
+	}
 } );
 
 export { IFCLoader };

+ 2 - 1
examples/jsm/loaders/ifc/web-ifc-api.js

@@ -539,7 +539,8 @@ var require_web_ifc = __commonJS((exports, module) => {
       function isFileURI(filename) {
         return hasPrefix(filename, fileURIPrefix);
       }
-      var wasmBinaryFile = "jsm/loaders/ifc/web-ifc.wasm";
+      var path = import.meta.url.substring(0, import.meta.url.lastIndexOf("/")+1);
+      var wasmBinaryFile = path + "web-ifc.wasm";
       if (!isDataURI(wasmBinaryFile)) {
         wasmBinaryFile = locateFile(wasmBinaryFile);
       }