Export the texture with three js files to a .OBJ file with a .MTL file

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

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

I saw this question , but the exporter seems to only export the grid. I also found this question , but this only applies to the importer.

The thing I wanted to implement is to make a 3D editor for printing, which will also export textures / colors, since there is already an exporter of .stl mesh for 3D printing. however, I did not find the grid + color / texture exporter for the three js :(

+7
source share
2 answers

I have expanded OBJExporter a bit. It will return an object containing the .obj part and the .mtl part. I just recorded it without testing, so there are probably errors, but I hope where to start.

I did not look for all the mtl values, I just used some standard values ​​besides the color and texture information. Perhaps I will improve it later. You also need to know the mtl file name. I am currently writing a static name for the obj part. When you save the files, the mtl file must be the same name as in the declared object. Otherwise 3ds max, etc. They will not 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 } } }; 
+7
source

here as you can save using Filesaver and JSZip

 var result = oexporter.parse(scene); zip.file('mymodel.obj', result.obj); zip.file('objmaterial.mtl', result.mtl); var zz=zip.generate({ type: 'blob' }); saveAs(zz, 'mymodel.zip'); 

However, my problem is that 3D models loaded into the scene from files are not saved. When loading a model using 3DBuilder, only what I created using the three.js functions appears.

0
source

All Articles