使用.MTL文件将三个js纹理模型导出到.OBJ [英] Export a three js textured model to a .OBJ with .MTL file
问题描述
我希望能够导出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文件(我见过obj带有 usemtl someTextureNameFromMTL的文件)
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可打印的编辑器,该编辑器也可以导出纹理/颜色已经是用于3D打印的.stl网格导出器。但是,我没有找到三个js的mesh + color / texture导出器:(
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扩展了一点
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\n';
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 + '\n';
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 + '\n';
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 + '\n';
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 + '\n';
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 + '\n';
nbNormals ++;
}
}
}
// material
if (material.name !== '')
output += 'usemtl ' + material.name + '\n';
else
output += 'usemtl material' + material.id + '\n';
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 ) + '\n';
}
} 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 + '\n';
else
mtlOutput += 'newmtl material' + mat.id + '\n';
mtlOutput += 'Ns 10.0000\n';
mtlOutput += 'Ni 1.5000\n';
mtlOutput += 'd 1.0000\n';
mtlOutput += 'Tr 0.0000\n';
mtlOutput += 'Tf 1.0000 1.0000 1.0000\n';
mtlOutput += 'illum 2\n';
mtlOutput += 'Ka ' + mat.color.r + ' ' + mat.color.g + ' ' + mat.color.b + ' ' + '\n';
mtlOutput += 'Kd ' + mat.color.r + ' ' + mat.color.g + ' ' + mat.color.b + ' ' + '\n';
mtlOutput += 'Ks 0.0000 0.0000 0.0000\n';
mtlOutput += 'Ke 0.0000 0.0000 0.0000\n';
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 + '\n';
mtlOutput += 'map_Kd ' + file + '\n';
}
}
return {
obj: output,
mtl: mtlOutput
}
}
};
这篇关于使用.MTL文件将三个js纹理模型导出到.OBJ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!