Commit 2ee6307b authored by amandaghassaei's avatar amandaghassaei

obj export

parent ced4f4b8
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.OBJExporter = function () {};
THREE.OBJExporter.prototype = {
constructor: THREE.OBJExporter,
parse: function ( object ) {
var output = '';
var indexVertex = 0;
var indexVertexUvs = 0;
var indexNormals = 0;
var vertex = new THREE.Vector3();
var normal = new THREE.Vector3();
var uv = new THREE.Vector2();
var i, j, k, l, m, face = [];
var parseMesh = function ( mesh ) {
var nbVertex = 0;
var nbNormals = 0;
var nbVertexUvs = 0;
var geometry = mesh.geometry;
var normalMatrixWorld = new THREE.Matrix3();
if ( geometry instanceof THREE.Geometry ) {
geometry = new THREE.BufferGeometry().setFromObject( mesh );
}
if ( geometry instanceof THREE.BufferGeometry ) {
// shortcuts
var vertices = geometry.getAttribute( 'position' );
var normals = geometry.getAttribute( 'normal' );
var uvs = geometry.getAttribute( 'uv' );
var indices = geometry.getIndex();
// name of the mesh object
output += 'o ' + mesh.name + '\n';
// name of the mesh material
if ( mesh.material && mesh.material.name ) {
output += 'usemtl ' + mesh.material.name + '\n';
}
// vertices
if( vertices !== undefined ) {
for ( i = 0, l = vertices.count; i < l; i ++, nbVertex++ ) {
vertex.x = vertices.getX( i );
vertex.y = vertices.getY( i );
vertex.z = vertices.getZ( i );
// transfrom the vertex to world space
vertex.applyMatrix4( mesh.matrixWorld );
// transform the vertex to export format
output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
}
}
// uvs
if( uvs !== undefined ) {
for ( i = 0, l = uvs.count; i < l; i ++, nbVertexUvs++ ) {
uv.x = uvs.getX( i );
uv.y = uvs.getY( i );
// transform the uv to export format
output += 'vt ' + uv.x + ' ' + uv.y + '\n';
}
}
// normals
if( normals !== undefined ) {
normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
for ( i = 0, l = normals.count; i < l; i ++, nbNormals++ ) {
normal.x = normals.getX( i );
normal.y = normals.getY( i );
normal.z = normals.getZ( i );
// transfrom the normal to world space
normal.applyMatrix3( normalMatrixWorld );
// transform the normal to export format
output += 'vn ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n';
}
}
// faces
if( indices !== null ) {
for ( i = 0, l = indices.count; i < l; i += 3 ) {
for( m = 0; m < 3; m ++ ){
j = indices.getX( i + m ) + 1;
face[ m ] = ( indexVertex + j ) + '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + '/' + ( indexNormals + j );
}
// transform the face to export format
output += 'f ' + face.join( ' ' ) + "\n";
}
} else {
for ( i = 0, l = vertices.count; i < l; i += 3 ) {
for( m = 0; m < 3; m ++ ){
j = i + m + 1;
face[ m ] = ( indexVertex + j ) + '/' + ( uvs ? ( indexVertexUvs + j ) : '' ) + '/' + ( indexNormals + j );
}
// transform the face to export format
output += 'f ' + face.join( ' ' ) + "\n";
}
}
} else {
console.warn( 'THREE.OBJExporter.parseMesh(): geometry type unsupported', geometry );
}
// update index
indexVertex += nbVertex;
indexVertexUvs += nbVertexUvs;
indexNormals += nbNormals;
};
var parseLine = function( line ) {
var nbVertex = 0;
var geometry = line.geometry;
var type = line.type;
if ( geometry instanceof THREE.Geometry ) {
geometry = new THREE.BufferGeometry().setFromObject( line );
}
if ( geometry instanceof THREE.BufferGeometry ) {
// shortcuts
var vertices = geometry.getAttribute( 'position' );
var indices = geometry.getIndex();
// name of the line object
output += 'o ' + line.name + '\n';
if( vertices !== undefined ) {
for ( i = 0, l = vertices.count; i < l; i ++, nbVertex++ ) {
vertex.x = vertices.getX( i );
vertex.y = vertices.getY( i );
vertex.z = vertices.getZ( i );
// transfrom the vertex to world space
vertex.applyMatrix4( line.matrixWorld );
// transform the vertex to export format
output += 'v ' + vertex.x + ' ' + vertex.y + ' ' + vertex.z + '\n';
}
}
if ( type === 'Line' ) {
output += 'l ';
for ( j = 1, l = vertices.count; j <= l; j++ ) {
output += ( indexVertex + j ) + ' ';
}
output += '\n';
}
if ( type === 'LineSegments' ) {
for ( j = 1, k = j + 1, l = vertices.count; j < l; j += 2, k = j + 1 ) {
output += 'l ' + ( indexVertex + j ) + ' ' + ( indexVertex + k ) + '\n';
}
}
} else {
console.warn('THREE.OBJExporter.parseLine(): geometry type unsupported', geometry );
}
// update index
indexVertex += nbVertex;
};
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
parseMesh( child );
}
if ( child instanceof THREE.Line ) {
parseLine( child );
}
} );
return output;
}
};
...@@ -359,6 +359,7 @@ ...@@ -359,6 +359,7 @@
<script type="text/javascript" src="dependencies/underscore-min.js"></script> <script type="text/javascript" src="dependencies/underscore-min.js"></script>
<script type="text/javascript" src="dependencies/FileSaver.min.js"></script> <script type="text/javascript" src="dependencies/FileSaver.min.js"></script>
<script type="text/javascript" src="dependencies/SVGLoader.js"></script> <script type="text/javascript" src="dependencies/SVGLoader.js"></script>
<script type="text/javascript" src="dependencies/OBJExporter.js"></script>
<script type="text/javascript" src="dependencies/path-data-polyfill.js"></script> <script type="text/javascript" src="dependencies/path-data-polyfill.js"></script>
<script type="text/javascript" src="dependencies/earcut.js"></script> <script type="text/javascript" src="dependencies/earcut.js"></script>
<script type="text/javascript" src="dependencies/numeric-1.2.6.js"></script> <script type="text/javascript" src="dependencies/numeric-1.2.6.js"></script>
...@@ -415,6 +416,7 @@ ...@@ -415,6 +416,7 @@
<li class="divider"></li> <li class="divider"></li>
<li><a id="exportFOLD" href="#">Save Simulation as FOLD...</a></li> <li><a id="exportFOLD" href="#">Save Simulation as FOLD...</a></li>
<li><a id="exportSTL" href="#">Save Simulation as STL...</a></li> <li><a id="exportSTL" href="#">Save Simulation as STL...</a></li>
<li><a id="exportOBJ" href="#">Save Simulation as OBJ...</a></li>
<li><a id="saveSVG" href="#">Save Pattern as SVG...</a></li> <li><a id="saveSVG" href="#">Save Pattern as SVG...</a></li>
<!--<li><a id="saveSVGScreenshot" href="#">Save SVG screenshot</a></li>--> <!--<li><a id="saveSVGScreenshot" href="#">Save SVG screenshot</a></li>-->
</ul> </ul>
...@@ -764,6 +766,29 @@ ...@@ -764,6 +766,29 @@
</div><!-- /.modal-content --> </div><!-- /.modal-content -->
</div><!-- /.modal-dialog --> </div><!-- /.modal-dialog -->
</div><!-- /.modal --> </div><!-- /.modal -->
<div class="modal fade" id="exportOBJModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-med">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<b>Export OBJ</b><br/><br/>
Filename: &nbsp;&nbsp;<input id="objFilename" value="" placeholder="" class="bigInput text form-control" type="text"> .stl<br/><br/>
Scale: &nbsp;&nbsp;<input value="" placeholder="" class="exportScale form-control" type="text"><br/><br/>
Dimensions: &nbsp;&nbsp;<b><span class="exportDimensions"></span></b><br/>
<span class="smallTxt">(the OBJ file format is unitless, but typically assumed to be either in inches or mm)</span><br/>
<label class="bigLabel checkbox" for="doublesidedOBJ">
<input id="doublesidedOBJ" data-toggle="checkbox" class="custom-checkbox layersSelector" type="checkbox"><span class="icons"><span class="icon-unchecked"></span><span class="icon-checked"></span></span>
Double Sided
</label>
</div>
<div class="modal-footer">
<button id="doOBJsave" type="button" class="actionButton btn btn-success" data-dismiss="modal">Save</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div class="modal fade" id="exportFOLDModal" tabindex="-1" role="dialog"> <div class="modal fade" id="exportFOLDModal" tabindex="-1" role="dialog">
<div class="modal-dialog modal-med"> <div class="modal-dialog modal-med">
<div class="modal-content"> <div class="modal-content">
......
...@@ -37,6 +37,11 @@ function initControls(globals){ ...@@ -37,6 +37,11 @@ function initControls(globals){
$("#stlFilename").val(globals.filename + " : " + parseInt(globals.creasePercent*100) + "PercentFolded"); $("#stlFilename").val(globals.filename + " : " + parseInt(globals.creasePercent*100) + "PercentFolded");
$('#exportSTLModal').modal('show'); $('#exportSTLModal').modal('show');
}); });
setLink("#exportOBJ", function(){
updateDimensions();
$("#objFilename").val(globals.filename + " : " + parseInt(globals.creasePercent*100) + "PercentFolded");
$('#exportOBJModal').modal('show');
});
setInput(".exportScale", globals.exportScale, function(val){ setInput(".exportScale", globals.exportScale, function(val){
globals.exportScale = val; globals.exportScale = val;
updateDimensions(); updateDimensions();
...@@ -48,6 +53,10 @@ function initControls(globals){ ...@@ -48,6 +53,10 @@ function initControls(globals){
} }
setCheckbox("#doublesidedSTL", globals.doublesidedSTL, function(val){ setCheckbox("#doublesidedSTL", globals.doublesidedSTL, function(val){
globals.doublesidedSTL = val; globals.doublesidedSTL = val;
//todo sync stuff
});
setCheckbox("#doublesidedOBJ", globals.doublesidedSTL, function(val){
globals.doublesidedSTL = val;
}); });
setLink(".units", function(e){ setLink(".units", function(e){
var units = $(e.target).data("id"); var units = $(e.target).data("id");
...@@ -62,6 +71,9 @@ function initControls(globals){ ...@@ -62,6 +71,9 @@ function initControls(globals){
setLink("#doSTLsave", function(){ setLink("#doSTLsave", function(){
saveSTL(); saveSTL();
}); });
setLink("#doOBJsave", function(){
saveOBJ();
});
setLink("#doFOLDsave", function(){ setLink("#doFOLDsave", function(){
saveFOLD(); saveFOLD();
}); });
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
* Created by amandaghassaei on 5/2/17. * Created by amandaghassaei on 5/2/17.
*/ */
function saveSTL(){ function makeSaveGEO(){
var geo = new THREE.Geometry().fromBufferGeometry( globals.model.getGeometry() ); var geo = new THREE.Geometry().fromBufferGeometry( globals.model.getGeometry() );
if (geo.vertices.length == 0 || geo.faces.length == 0) { if (geo.vertices.length == 0 || geo.faces.length == 0) {
...@@ -24,13 +23,27 @@ function saveSTL(){ ...@@ -24,13 +23,27 @@ function saveSTL(){
geo.faces.push(new THREE.Face3(face.a, face.c, face.b)); geo.faces.push(new THREE.Face3(face.a, face.c, face.b));
} }
} }
return geo;
}
function saveSTL(){
var data = []; var data = [];
data.push({geo: geo, offset:new THREE.Vector3(0,0,0), orientation:new THREE.Quaternion(0,0,0,1)}); data.push({geo: makeSaveGEO(), offset:new THREE.Vector3(0,0,0), orientation:new THREE.Quaternion(0,0,0,1)});
var stlBin = geometryToSTLBin(data); var stlBin = geometryToSTLBin(data);
if (!stlBin) return; if (!stlBin) return;
var blob = new Blob([stlBin], {type: 'application/octet-binary'}); var blob = new Blob([stlBin], {type: 'application/octet-binary'});
var filename = $("#stlFilename").val(); var filename = $("#stlFilename").val();
if (filename == "") filename = globals.filename; if (filename == "") filename = globals.filename;
saveAs(blob, filename + ".stl"); saveAs(blob, filename + ".stl");
}
function saveOBJ(){
var exporter = new THREE.OBJExporter();
var result = exporter.parse (new THREE.Mesh(makeSaveGEO()));
if (!result) return;
var blob = new Blob([result], {type: 'application/octet-binary'});
var filename = $("#objFilename").val();
if (filename == "") filename = globals.filename;
saveAs(blob, filename + ".obj");
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment