diff --git a/IMG_20200426_151126873.jpg b/IMG_20200426_151126873.jpg new file mode 100644 index 0000000..b91d5fd Binary files /dev/null and b/IMG_20200426_151126873.jpg differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e0380a --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# 3DprintParametricShape +added 3D-print option (aka STL output) to Parametric Surface example. + +Used it to print möbius band inspired shape; ellips moved+rotated along circle: +![möbius band inspired shape on my finger](https://raw.githubusercontent.com/steltenpower/3DprintParametricShape/master/IMG_20200426_151126873.jpg) + +You need to websearch for "repair STL" too, as the result will have a gap (which is a problem for your 3D-printer, even though you don't see it on your screen) diff --git a/Three.js/Graphulus-Surface.html b/Three.js/Graphulus-Surface.html index 3ac6f38..42ae7c0 100644 --- a/Three.js/Graphulus-Surface.html +++ b/Three.js/Graphulus-Surface.html @@ -21,6 +21,9 @@ + + + @@ -277,7 +280,7 @@ gui_xText.setValue("cos(u)*(a + b*cos(v))"); gui_yText.setValue("sin(u)*(a + b*cos(v))"); gui_zText.setValue("b*sin(v)"); - gui_uMin.setValue(0); gui_uMax.setValue(6.283); + gui_uMin.setValue(0); gui_uMax.setValue(6.283); // please add option to CLOSE design, repeat first value at the end. Now the design is leak, which gives problems when trying to 3D-print it. gui_vMin.setValue(0); gui_vMax.setValue(6.283); gui_a.setValue(3); gui_b.setValue(1); @@ -309,9 +312,9 @@ function update() { - if ( keyboard.pressed("z") ) + if ( keyboard.pressed("p") ) { - // do something + var myStlString = stlFromGeometry( graphGeometry, {download:true, useObjectPosition:false} ) // maybe a proper button too? } controls.update(); diff --git a/Three.js/js/THREE2STL.js b/Three.js/js/THREE2STL.js new file mode 100644 index 0000000..018f29f --- /dev/null +++ b/Three.js/js/THREE2STL.js @@ -0,0 +1,86 @@ +function stlFromGeometry( geometry, options ) { + + // calculate the faces and normals if they are not yet present + geometry.computeFaceNormals() + + var addX = 0 + var addY = 0 + var addZ = 0 + var download = false + + if ( options ) { + if ( options.useObjectPosition ) { + addX = geometry.mesh.position.x + addY = geometry.mesh.position.y + addZ = geometry.mesh.position.z + } + + if ( options.download ) { + download = true + } + } + + + var facetToStl = function( verts, normal ) { + var faceStl = '' + faceStl += 'facet normal ' + normal.x + ' ' + normal.y + ' ' + normal.z + '\n' + faceStl += 'outer loop\n' + + for ( var j = 0; j < 3; j++ ) { + var vert = verts[j] + faceStl += 'vertex ' + (vert.x+addX) + ' ' + (vert.y+addY) + ' ' + (vert.z+addZ) + '\n' + } + + faceStl += 'endloop\n' + faceStl += 'endfacet\n' + + return faceStl + } + + // start bulding the STL string + var stl = '' + stl += 'solid\n' + + for ( var i = 0; i < geometry.faces.length; i++ ) { + var face = geometry.faces[i] + + // if we have just a griangle, that's easy. just write them to the file + if ( face.d === undefined ) { + var verts = [ + geometry.vertices[ face.a ], + geometry.vertices[ face.b ], + geometry.vertices[ face.c ] + ] + + stl += facetToStl( verts, face.normal ) + + } else { + // if it's a quad, we need to triangulate it first + // split the quad into two triangles: abd and bcd + var verts = [] + verts[0] = [ + geometry.vertices[ face.a ], + geometry.vertices[ face.b ], + geometry.vertices[ face.d ] + ] + verts[1] = [ + geometry.vertices[ face.b ], + geometry.vertices[ face.c ], + geometry.vertices[ face.d ] + ] + + for ( var k = 0; k<2; k++ ) { + stl += facetToStl( verts[k], face.normal ) + } + + } + } + + stl += 'endsolid' + + if ( download ) { + document.location = 'data:Application/octet-stream, ' + encodeURIComponent( stl ) + } + + return stl +}