将三个 js 纹理模型导出为带有 .MTL 文件的 .OBJ [英] Export a three js textured model to a .OBJ with .MTL file

查看:21
本文介绍了将三个 js 纹理模型导出为带有 .MTL 文件的 .OBJ的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够像在本示例中一样导出 obj 文件 http://threejs.org/examples/#webgl_exporter_obj

I would like to be able to export an obj file just like in this example http://threejs.org/examples/#webgl_exporter_obj

但是,我想在 .mtl 纹理文件中导出带有相应纹理的 .obj 文件(我见过带有usemtl someTextureNameFromMTL"的 obj 文件)

However, i would like to export the .obj file with corresponding textures in the .mtl texture file (i have seen obj files with "usemtl someTextureNameFromMTL")

我看过这个问题但出口商似乎只出口网.我还发现 这个问题但只讨论进口商.

I have seen this question but the exporter seems to be exporting only mesh. I have also found this question but that discusses importer only.

我想要实现的是制作一个 3d 可打印的编辑​​器,它也可以导出纹理/颜色,因为已经有一个 .stl 网格导出器用于 3d 打印.但是,我没有发现三个 js 的网格+颜色/纹理导出器 :(

The thing i wanted to implement is to make a 3d printable editor that would also export textures/colors, as there already is a .stl mesh exporter for 3d printing. however, i have found no mesh+color/texture exporter for three js :(

推荐答案

我稍微扩展了 OBJExporter.它将返回一个包含 .obj 部分和 .mtl 部分的对象.我只是没有测试就写下来,所以可能有错误,但我希望它是一个开始.

I have extended the OBJExporter a little bit. It will return an object containing the .obj part and the .mtl part. I just wrote it down without testing, so there are probably bugs, but I hope it is something to start with.

我没有查找所有的 mtl 值,我只是使用了一些除了颜色和纹理信息之外的标准值.也许以后我会改进它.您还需要了解 mtl 文件名.目前,我正在为 obj 部分写一个静态名称.保存文件时,mtl 文件需要与声明的 obj 文件同名.否则 3ds max 等将无法读取.

I haven't looked up all the mtl values, I just used some standards values apart from color and texture information. Maybe I will improve it later on. You also need to be aware of the mtl filename. Currently, I'm writing a static name to the obj part. When you save the files the mtl file needs to be the same name as in the obj file declared. Otherwise 3ds max etc. won't read it.

/**
 * @author mrdoob / http://mrdoob.com/
 */

THREE.OBJExporter = function () {};

THREE.OBJExporter.prototype = {

	constructor: THREE.OBJExporter,

	parse: function ( object ) {

	var output = '';
		var materials = {};

		var indexVertex = 0;
		var indexVertexUvs = 0;
		var indexNormals = 0;
      	
	var mtlFileName = 'objmaterial'; // maybe this value can be passed as parameter
	output += 'mtllib ' + mtlFileName +  '.mtl
';

		var parseMesh = function ( mesh ) {

			var nbVertex = 0;
			var nbVertexUvs = 0;
			var nbNormals = 0;

			var geometry = mesh.geometry;
			var material = mesh.material;

			if ( geometry instanceof THREE.Geometry ) {

				output += 'o ' + mesh.name + '
';

				var vertices = geometry.vertices;

				for ( var i = 0, l = vertices.length; i < l; i ++ ) {

					var vertex = vertices[ i ].clone();
					vertex.applyMatrix4( mesh.matrixWorld );

					output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '
';

					nbVertex ++;

				}

				// uvs

				var faces = geometry.faces;
				var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
				var hasVertexUvs = faces.length === faceVertexUvs.length;

				if ( hasVertexUvs ) {

					for ( var i = 0, l = faceVertexUvs.length; i < l; i ++ ) {

						var vertexUvs = faceVertexUvs[ i ];

						for ( var j = 0, jl = vertexUvs.length; j < jl; j ++ ) {

							var uv = vertexUvs[ j ];

							output += 'vt ' + uv.x + ' ' + uv.y + '
';

							nbVertexUvs ++;

						}

					}

				}

				// normals

				var normalMatrixWorld = new THREE.Matrix3();
				normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );

				for ( var i = 0, l = faces.length; i < l; i ++ ) {

					var face = faces[ i ];
					var vertexNormals = face.vertexNormals;

					if ( vertexNormals.length === 3 ) {

						for ( var j = 0, jl = vertexNormals.length; j < jl; j ++ ) {

							var normal = vertexNormals[ j ].clone();
							normal.applyMatrix3( normalMatrixWorld );

							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '
';

							nbNormals ++;

						}

					} else {

						var normal = face.normal.clone();
						normal.applyMatrix3( normalMatrixWorld );

						for ( var j = 0; j < 3; j ++ ) {

							output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '
';

							nbNormals ++;

						}

					}

				}
              
			// material
              
			if (material.name !== '')
				output += 'usemtl ' + material.name + '
';
			else
				output += 'usemtl material' + material.id + '
';
              
			materials[material.id] = material;

				// faces


				for ( var i = 0, j = 1, l = faces.length; i < l; i ++, j += 3 ) {

					var face = faces[ i ];

					output += 'f ';
					output += ( indexVertex + face.a + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j     ) : '' ) + '/' + ( indexNormals + j     ) + ' ';
					output += ( indexVertex + face.b + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + 1 ) : '' ) + '/' + ( indexNormals + j + 1 ) + ' ';
					output += ( indexVertex + face.c + 1 ) + '/' + ( hasVertexUvs ? ( indexVertexUvs + j + 2 ) : '' ) + '/' + ( indexNormals + j + 2 ) + '
';

				}

			} else {

				console.warn( 'THREE.OBJExporter.parseMesh(): geometry type unsupported', mesh );
				// TODO: Support only BufferGeometry and use use setFromObject()

			}

			// update index
			indexVertex += nbVertex;
			indexVertexUvs += nbVertexUvs;
			indexNormals += nbNormals;

		};

		object.traverse( function ( child ) {

			if ( child instanceof THREE.Mesh ) parseMesh( child );

		} );
      		
	// mtl output
      
	var mtlOutput = '';
      
	for (var key in materials) {
        
		var mat = materials[key];
          
		if (mat.name !== '')
			mtlOutput += 'newmtl ' + mat.name + '
';
		else
			mtlOutput += 'newmtl material' + mat.id + '
';
          
		mtlOutput += 'Ns 10.0000
';
		mtlOutput += 'Ni 1.5000
';
		mtlOutput += 'd 1.0000
';
		mtlOutput += 'Tr 0.0000
';
		mtlOutput += 'Tf 1.0000 1.0000 1.0000
';
		mtlOutput += 'illum 2
';
		mtlOutput += 'Ka ' + mat.color.r + ' ' + mat.color.g + ' ' + mat.color.b + ' ' + '
';
		mtlOutput += 'Kd ' + mat.color.r + ' ' + mat.color.g + ' ' + mat.color.b + ' ' + '
';
		mtlOutput += 'Ks 0.0000 0.0000 0.0000
';
		mtlOutput += 'Ke 0.0000 0.0000 0.0000
';
          
		if (mat.map && mat.map instanceof THREE.Texture) {
          
			var file = mat.map.image.currentSrc.slice( mat.map.image.currentSrc.slice.lastIndexOf("/"), mat.map.image.currentSrc.length - 1 );
            
			mtlOutput += 'map_Ka ' + file + '
';
			mtlOutput += 'map_Kd ' + file + '
';
            
		}
          
	}

	return {
		obj: output,
		mtl: mtlOutput
	}

	}

};

这篇关于将三个 js 纹理模型导出为带有 .MTL 文件的 .OBJ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆