|
@@ -10,20 +10,31 @@
|
|
|
* - Object Resources (Meshes and Components)
|
|
|
* - Material Resources (Base Materials)
|
|
|
*
|
|
|
- * 3MF Materials and Properties Extension (e.g. textures) are not yet supported.
|
|
|
+ * 3MF Materials and Properties Extension are only partially supported.
|
|
|
*
|
|
|
+ * - Texture 2D
|
|
|
+ * - Texture 2D Groups
|
|
|
*/
|
|
|
|
|
|
import {
|
|
|
BufferAttribute,
|
|
|
BufferGeometry,
|
|
|
+ ClampToEdgeWrapping,
|
|
|
FileLoader,
|
|
|
+ Float32BufferAttribute,
|
|
|
Group,
|
|
|
+ LinearFilter,
|
|
|
+ LinearMipmapLinearFilter,
|
|
|
Loader,
|
|
|
LoaderUtils,
|
|
|
Matrix4,
|
|
|
Mesh,
|
|
|
- MeshPhongMaterial
|
|
|
+ MeshPhongMaterial,
|
|
|
+ MirroredRepeatWrapping,
|
|
|
+ NearestFilter,
|
|
|
+ RepeatWrapping,
|
|
|
+ TextureLoader,
|
|
|
+ sRGBEncoding
|
|
|
} from "../../../build/three.module.js";
|
|
|
|
|
|
var ThreeMFLoader = function ( manager ) {
|
|
@@ -55,6 +66,8 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
parse: function ( data ) {
|
|
|
|
|
|
var scope = this;
|
|
|
+ var textureLoader = new TextureLoader( this.manager );
|
|
|
+ var textureMap = {};
|
|
|
|
|
|
function loadDocument( data ) {
|
|
|
|
|
@@ -62,12 +75,14 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
var file = null;
|
|
|
|
|
|
var relsName;
|
|
|
+ var modelRelsName;
|
|
|
var modelPartNames = [];
|
|
|
var printTicketPartNames = [];
|
|
|
var texturesPartNames = [];
|
|
|
var otherPartNames = [];
|
|
|
|
|
|
var rels;
|
|
|
+ var modelRels;
|
|
|
var modelParts = {};
|
|
|
var printTicketParts = {};
|
|
|
var texturesParts = {};
|
|
@@ -94,6 +109,10 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
relsName = file;
|
|
|
|
|
|
+ } else if ( file.match( /3D\/_rels\/.*\.model\.rels$/ ) ) {
|
|
|
+
|
|
|
+ modelRelsName = file;
|
|
|
+
|
|
|
} else if ( file.match( /^3D\/.*\.model$/ ) ) {
|
|
|
|
|
|
modelPartNames.push( file );
|
|
@@ -102,7 +121,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
printTicketPartNames.push( file );
|
|
|
|
|
|
- } else if ( file.match( /^3D\/Textures\/.*/ ) ) {
|
|
|
+ } else if ( file.match( /^3D\/Texture\/.*/ ) ) {
|
|
|
|
|
|
texturesPartNames.push( file );
|
|
|
|
|
@@ -114,10 +133,24 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
var relsView = new Uint8Array( zip.file( relsName ).asArrayBuffer() );
|
|
|
var relsFileText = LoaderUtils.decodeText( relsView );
|
|
|
rels = parseRelsXml( relsFileText );
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
+ if ( modelRelsName ) {
|
|
|
+
|
|
|
+ var relsView = new Uint8Array( zip.file( modelRelsName ).asArrayBuffer() );
|
|
|
+ var relsFileText = LoaderUtils.decodeText( relsView );
|
|
|
+ modelRels = parseRelsXml( relsFileText );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
for ( var i = 0; i < modelPartNames.length; i ++ ) {
|
|
|
|
|
|
var modelPart = modelPartNames[ i ];
|
|
@@ -159,15 +192,18 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
for ( var i = 0; i < texturesPartNames.length; i ++ ) {
|
|
|
|
|
|
var texturesPartName = texturesPartNames[ i ];
|
|
|
- texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asBinary();
|
|
|
+ texturesParts[ texturesPartName ] = zip.file( texturesPartName ).asArrayBuffer();
|
|
|
|
|
|
}
|
|
|
|
|
|
return {
|
|
|
rels: rels,
|
|
|
+ modelRels: modelRels,
|
|
|
model: modelParts,
|
|
|
printTicket: printTicketParts,
|
|
|
texture: texturesParts,
|
|
@@ -244,6 +280,49 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function parseTexture2DNode( texture2DNode ) {
|
|
|
+
|
|
|
+ var texture2dData = {
|
|
|
+ id: texture2DNode.getAttribute( 'id' ), // required
|
|
|
+ path: texture2DNode.getAttribute( 'path' ), // required
|
|
|
+ contenttype: texture2DNode.getAttribute( 'contenttype' ), // required
|
|
|
+ tilestyleu: texture2DNode.getAttribute( 'tilestyleu' ),
|
|
|
+ tilestylev: texture2DNode.getAttribute( 'tilestylev' ),
|
|
|
+ filter: texture2DNode.getAttribute( 'filter' ),
|
|
|
+ };
|
|
|
+
|
|
|
+ return texture2dData;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function parseTextures2DGroupNodes( texture2DGroupNode ) {
|
|
|
+
|
|
|
+ var texture2DGroupData = {
|
|
|
+ id: texture2DGroupNode.getAttribute( 'id' ), // required
|
|
|
+ texid: texture2DGroupNode.getAttribute( 'texid' ), // required
|
|
|
+ displaypropertiesid: texture2DGroupNode.getAttribute( 'displaypropertiesid' )
|
|
|
+ };
|
|
|
+
|
|
|
+ var tex2coordNodes = texture2DGroupNode.querySelectorAll( 'tex2coord' );
|
|
|
+
|
|
|
+ var uvs = [];
|
|
|
+
|
|
|
+ for ( var i = 0; i < tex2coordNodes.length; i ++ ) {
|
|
|
+
|
|
|
+ var tex2coordNode = tex2coordNodes[ i ];
|
|
|
+ var u = tex2coordNode.getAttribute( 'u' );
|
|
|
+ var v = tex2coordNode.getAttribute( 'v' );
|
|
|
+
|
|
|
+ uvs.push( parseFloat( u ), parseFloat( v ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ texture2DGroupData[ 'uvs' ] = new Float32Array( uvs );
|
|
|
+
|
|
|
+ return texture2DGroupData;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
function parseBasematerialNode( basematerialNode ) {
|
|
|
|
|
|
var basematerialData = {};
|
|
@@ -273,13 +352,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
- meshData[ 'vertices' ] = new Float32Array( vertices.length );
|
|
|
-
|
|
|
- for ( var i = 0; i < vertices.length; i ++ ) {
|
|
|
-
|
|
|
- meshData[ 'vertices' ][ i ] = vertices[ i ];
|
|
|
-
|
|
|
- }
|
|
|
+ meshData[ 'vertices' ] = new Float32Array( vertices );
|
|
|
|
|
|
var triangleProperties = [];
|
|
|
var triangles = [];
|
|
@@ -333,13 +406,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
}
|
|
|
|
|
|
meshData[ 'triangleProperties' ] = triangleProperties;
|
|
|
- meshData[ 'triangles' ] = new Uint32Array( triangles.length );
|
|
|
-
|
|
|
- for ( var i = 0; i < triangles.length; i ++ ) {
|
|
|
-
|
|
|
- meshData[ 'triangles' ][ i ] = triangles[ i ];
|
|
|
-
|
|
|
- }
|
|
|
+ meshData[ 'triangles' ] = new Uint32Array( triangles );
|
|
|
|
|
|
return meshData;
|
|
|
|
|
@@ -487,6 +554,34 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
+ resourcesData[ 'texture2d' ] = {};
|
|
|
+ var textures2DNodes = resourcesNode.querySelectorAll( 'texture2d' );
|
|
|
+
|
|
|
+ for ( var i = 0; i < textures2DNodes.length; i ++ ) {
|
|
|
+
|
|
|
+ var textures2DNode = textures2DNodes[ i ];
|
|
|
+ var texture2DData = parseTexture2DNode( textures2DNode );
|
|
|
+ resourcesData[ 'texture2d' ][ texture2DData[ 'id' ] ] = texture2DData;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ resourcesData[ 'texture2dgroup' ] = {};
|
|
|
+ var textures2DGroupNodes = resourcesNode.querySelectorAll( 'texture2dgroup' );
|
|
|
+
|
|
|
+ for ( var i = 0; i < textures2DGroupNodes.length; i ++ ) {
|
|
|
+
|
|
|
+ var textures2DGroupNode = textures2DGroupNodes[ i ];
|
|
|
+ var textures2DGroupData = parseTextures2DGroupNodes( textures2DGroupNode );
|
|
|
+ resourcesData[ 'texture2dgroup' ][ textures2DGroupData[ 'id' ] ] = textures2DGroupData;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
resourcesData[ 'object' ] = {};
|
|
|
var objectNodes = resourcesNode.querySelectorAll( 'object' );
|
|
|
|
|
@@ -560,15 +655,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function buildMesh( meshData, objects, modelData, objectData ) {
|
|
|
-
|
|
|
- // geometry
|
|
|
-
|
|
|
- var geometry = new BufferGeometry();
|
|
|
- geometry.setIndex( new BufferAttribute( meshData[ 'triangles' ], 1 ) );
|
|
|
- geometry.setAttribute( 'position', new BufferAttribute( meshData[ 'vertices' ], 3 ) );
|
|
|
-
|
|
|
- // groups
|
|
|
+ function buildGroups( geometry, modelData, meshData ) {
|
|
|
|
|
|
var basematerialsData = modelData[ 'resources' ][ 'basematerials' ];
|
|
|
var triangleProperties = meshData[ 'triangleProperties' ];
|
|
@@ -590,7 +677,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
if ( currentMaterialIndex === triangleProperty.p1 ) {
|
|
|
|
|
|
- count += 3; // primitves per triangle
|
|
|
+ count += 3; // primitives per triangle
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -608,20 +695,215 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
if ( geometry.groups.length > 0 ) mergeGroups( geometry );
|
|
|
|
|
|
- geometry.computeBoundingSphere();
|
|
|
+ }
|
|
|
+
|
|
|
+ function buildGeometry( modelData, meshData, objectData ) {
|
|
|
+
|
|
|
+ var geometry = new BufferGeometry();
|
|
|
+ geometry.setIndex( new BufferAttribute( meshData[ 'triangles' ], 1 ) );
|
|
|
+ geometry.setAttribute( 'position', new BufferAttribute( meshData[ 'vertices' ], 3 ) );
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ var texture2dgroups = modelData.resources.texture2dgroup;
|
|
|
+
|
|
|
+ if ( texture2dgroups ) {
|
|
|
+
|
|
|
+ var textureCoordinates = [];
|
|
|
+
|
|
|
+ var triangleProperties = meshData[ 'triangleProperties' ];
|
|
|
+ var texture2dgroupObjectLevel;
|
|
|
+
|
|
|
+ // check reference to texture coordinates on object level
|
|
|
+
|
|
|
+ var texid;
|
|
|
+ var pid = objectData.pid;
|
|
|
+
|
|
|
+ if ( pid && texture2dgroups[ pid ] ) texture2dgroupObjectLevel = texture2dgroups[ pid ];
|
|
|
+
|
|
|
+ // process all triangles
|
|
|
+
|
|
|
+ for ( var i = 0, l = triangleProperties.length; i < l; i ++ ) {
|
|
|
+
|
|
|
+ var texture2dgroup = texture2dgroupObjectLevel;
|
|
|
+ var triangleProperty = triangleProperties[ i ];
|
|
|
+ pid = triangleProperty.pid;
|
|
|
+
|
|
|
+ // overwrite existing resource reference if necessary
|
|
|
+
|
|
|
+ if ( pid && texture2dgroups[ pid ] ) texture2dgroup = texture2dgroups[ pid ];
|
|
|
+
|
|
|
+ if ( texture2dgroup ) {
|
|
|
+
|
|
|
+ texid = texture2dgroup.texid; // the loader only supports a single texture for a single geometry right now (and not per face)
|
|
|
+ var uvs = texture2dgroup.uvs;
|
|
|
+
|
|
|
+ textureCoordinates.push( uvs[ ( triangleProperty.p1 * 2 ) + 0 ] );
|
|
|
+ textureCoordinates.push( uvs[ ( triangleProperty.p1 * 2 ) + 1 ] );
|
|
|
+
|
|
|
+ textureCoordinates.push( uvs[ ( triangleProperty.p2 * 2 ) + 0 ] );
|
|
|
+ textureCoordinates.push( uvs[ ( triangleProperty.p2 * 2 ) + 1 ] );
|
|
|
+
|
|
|
+ textureCoordinates.push( uvs[ ( triangleProperty.p3 * 2 ) + 0 ] );
|
|
|
+ textureCoordinates.push( uvs[ ( triangleProperty.p3 * 2 ) + 1 ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( textureCoordinates.length > 0 ) {
|
|
|
+
|
|
|
+ // uvs are defined on face level so the same vertex can have multiple uv coordinates
|
|
|
+
|
|
|
+ geometry = geometry.toNonIndexed();
|
|
|
+ geometry.setAttribute( 'uv', new Float32BufferAttribute( textureCoordinates, 2 ) );
|
|
|
+ geometry.__texid = texid; // save the relationship between texture coordinates and texture
|
|
|
+
|
|
|
+ return geometry;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return geometry;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function buildTexture( geometry, modelData, textureData ) {
|
|
|
+
|
|
|
+ var texid = geometry.__texid;
|
|
|
+
|
|
|
+ if ( texid !== undefined ) {
|
|
|
+
|
|
|
+ delete geometry.__texid;
|
|
|
+
|
|
|
+ if ( textureMap[ texid ] !== undefined ) {
|
|
|
+
|
|
|
+ return textureMap[ texid ];
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ var texture2ds = modelData.resources.texture2d;
|
|
|
+ var texture2d = texture2ds[ texid ];
|
|
|
+
|
|
|
+ if ( texture2d ) {
|
|
|
+
|
|
|
+ var data = textureData[ texture2d.path ];
|
|
|
+ var type = texture2d.contenttype;
|
|
|
+
|
|
|
+ var blob = new Blob( [ data ], { type: type } );
|
|
|
+ var sourceURI = URL.createObjectURL( blob );
|
|
|
+
|
|
|
+ var texture = textureLoader.load( sourceURI, function () {
|
|
|
+
|
|
|
+ URL.revokeObjectURL( sourceURI );
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
+ texture.encoding = sRGBEncoding;
|
|
|
+
|
|
|
+ // texture parameters
|
|
|
+
|
|
|
+ switch ( texture2d.tilestyleu ) {
|
|
|
+
|
|
|
+ case 'wrap':
|
|
|
+ texture.wrapS = RepeatWrapping;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'mirror':
|
|
|
+ texture.wrapS = MirroredRepeatWrapping;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'none':
|
|
|
+ case 'clamp':
|
|
|
+ texture.wrapS = ClampToEdgeWrapping;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ texture.wrapS = RepeatWrapping;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ switch ( texture2d.tilestylev ) {
|
|
|
+
|
|
|
+ case 'wrap':
|
|
|
+ texture.wrapT = RepeatWrapping;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'mirror':
|
|
|
+ texture.wrapT = MirroredRepeatWrapping;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'none':
|
|
|
+ case 'clamp':
|
|
|
+ texture.wrapT = ClampToEdgeWrapping;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ texture.wrapT = RepeatWrapping;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ switch ( texture2d.filter ) {
|
|
|
+
|
|
|
+ case 'auto':
|
|
|
+ texture.magFilter = LinearFilter;
|
|
|
+ texture.minFilter = LinearMipmapLinearFilter;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'linear':
|
|
|
+ texture.magFilter = LinearFilter;
|
|
|
+ texture.minFilter = LinearFilter;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'nearest':
|
|
|
+ texture.magFilter = NearestFilter;
|
|
|
+ texture.minFilter = NearestFilter;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ texture.magFilter = LinearFilter;
|
|
|
+ texture.minFilter = LinearMipmapLinearFilter;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ textureMap[ texid ] = texture;
|
|
|
+
|
|
|
+ return texture;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function buildMesh( meshData, objects, modelData, textureData, objectData ) {
|
|
|
+
|
|
|
+ var geometry = buildGeometry( modelData, meshData, objectData );
|
|
|
+ var texture = buildTexture( geometry, modelData, textureData );
|
|
|
+
|
|
|
+ // groups
|
|
|
+
|
|
|
+ buildGroups( geometry, modelData, meshData );
|
|
|
|
|
|
// material
|
|
|
|
|
|
- var material;
|
|
|
+ var material = null;
|
|
|
|
|
|
// add material if an object-level definition is present
|
|
|
|
|
|
+ var basematerialsData = modelData[ 'resources' ][ 'basematerials' ];
|
|
|
+
|
|
|
if ( basematerialsData && ( basematerialsData.id === objectData.pid ) ) {
|
|
|
|
|
|
var materialIndex = objectData.pindex;
|
|
|
var basematerialData = basematerialsData.basematerials[ materialIndex ];
|
|
|
|
|
|
- material = getBuild( basematerialData, objects, modelData, objectData, buildBasematerial );
|
|
|
+ material = getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -636,8 +918,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
var group = groups[ i ];
|
|
|
var basematerialData = basematerialsData.basematerials[ group.materialIndex ];
|
|
|
-
|
|
|
- material.push( getBuild( basematerialData, objects, modelData, objectData, buildBasematerial ) );
|
|
|
+ material.push( getBuild( basematerialData, objects, modelData, textureData, objectData, buildBasematerial ) );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -645,7 +926,19 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
// default material
|
|
|
|
|
|
- if ( material === undefined ) material = new MeshPhongMaterial( { color: 0xaaaaff, flatShading: true } );
|
|
|
+ if ( material === null ) {
|
|
|
+
|
|
|
+ if ( texture === null ) {
|
|
|
+
|
|
|
+ material = new MeshPhongMaterial( { color: 0xaaaaff, flatShading: true } );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ material = new MeshPhongMaterial( { map: texture, flatShading: true } );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
return new Mesh( geometry, material );
|
|
|
|
|
@@ -767,11 +1060,11 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function getBuild( data, objects, modelData, objectData, builder ) {
|
|
|
+ function getBuild( data, objects, modelData, textureData, objectData, builder ) {
|
|
|
|
|
|
if ( data.build !== undefined ) return data.build;
|
|
|
|
|
|
- data.build = builder( data, objects, modelData, objectData );
|
|
|
+ data.build = builder( data, objects, modelData, textureData, objectData );
|
|
|
|
|
|
return data.build;
|
|
|
|
|
@@ -803,7 +1096,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function buildComposite( compositeData, objects, modelData ) {
|
|
|
+ function buildComposite( compositeData, objects, modelData, textureData ) {
|
|
|
|
|
|
var composite = new Group();
|
|
|
|
|
@@ -814,7 +1107,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
if ( build === undefined ) {
|
|
|
|
|
|
- buildObject( component.objectId, objects, modelData );
|
|
|
+ buildObject( component.objectId, objects, modelData, textureData );
|
|
|
build = objects[ component.objectId ];
|
|
|
|
|
|
}
|
|
@@ -839,7 +1132,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function buildObject( objectId, objects, modelData ) {
|
|
|
+ function buildObject( objectId, objects, modelData, textureData ) {
|
|
|
|
|
|
var objectData = modelData[ 'resources' ][ 'object' ][ objectId ];
|
|
|
|
|
@@ -852,13 +1145,13 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
applyExtensions( extensions, meshData, modelXml );
|
|
|
|
|
|
- objects[ objectData.id ] = getBuild( meshData, objects, modelData, objectData, buildMesh );
|
|
|
+ objects[ objectData.id ] = getBuild( meshData, objects, modelData, textureData, objectData, buildMesh );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
var compositeData = objectData[ 'components' ];
|
|
|
|
|
|
- objects[ objectData.id ] = getBuild( compositeData, objects, modelData, objectData, buildComposite );
|
|
|
+ objects[ objectData.id ] = getBuild( compositeData, objects, modelData, textureData, objectData, buildComposite );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -867,8 +1160,26 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
function buildObjects( data3mf ) {
|
|
|
|
|
|
var modelsData = data3mf.model;
|
|
|
+ var modelRels = data3mf.modelRels;
|
|
|
var objects = {};
|
|
|
var modelsKeys = Object.keys( modelsData );
|
|
|
+ var textureData = {};
|
|
|
+
|
|
|
+ // evaluate model relationship to a texture
|
|
|
+
|
|
|
+ if ( modelRels ) {
|
|
|
+
|
|
|
+ var textureKey = modelRels.target.substring( 1 );
|
|
|
+
|
|
|
+ if ( data3mf.texture[ textureKey ] ) {
|
|
|
+
|
|
|
+ textureData[ modelRels.target ] = data3mf.texture[ textureKey ];
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // start build
|
|
|
|
|
|
for ( var i = 0; i < modelsKeys.length; i ++ ) {
|
|
|
|
|
@@ -881,7 +1192,7 @@ ThreeMFLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
|
|
|
|
|
|
var objectId = objectIds[ j ];
|
|
|
|
|
|
- buildObject( objectId, objects, modelData );
|
|
|
+ buildObject( objectId, objects, modelData, textureData );
|
|
|
|
|
|
}
|
|
|
|