#Code to turn a 3d function in R into a stl file that can be 3D printed
#Right now requires an additional step in MeshLab to make the surface into a solid.
#Do Filter->Remeshing->Uniform Mesh Resampling with settings: precision at 1.0%, 
#offset at 53.0%, and absolute distance selected
#Laura Perovich Oct 2012

#Load package misc3d that includes surfaceTriangles function
library(misc3d)

#Define character constants used in the stl files
tristart1<-"facet normal 0 0 0"
tristart2<-" outer loop"
triend1<-" endloop"
triend2<-"endfacet"
startline1<-"+"
startline2<-" solid LAURA"
endline<-" endsolid LAURA"

#Make a function that will make each facet from data returned from surfaceTriangles applied to a function
#(probably a more elegant way to do this?)
makefacet<-function(data){
facetvector<-c()
for (i in 1:nrow(data[[1]])){
v1<-paste("  vertex", as.character(data[[1]][i, 1]), as.character(data[[1]][i, 2]), as.character(data[[1]][i, 3]), sep=" ")
v2<-paste("  vertex", as.character(data[[2]][i, 1]), as.character(data[[2]][i, 2]), as.character(data[[2]][i, 3]), sep=" ")
v3<-paste("  vertex", as.character(data[[3]][i, 1]), as.character(data[[3]][i, 2]), as.character(data[[3]][i, 3]), sep=" ")
facetvector<-c(facetvector, tristart1, tristart2, v1, v2, v3, triend1, triend2) 
}
return(facetvector)
}

#Make a function that puts the facets together with the file headers and writes it out
makestl<-function(location, facetvector){
fileConn<-file(location)
writeLines(c(startline1, startline2, facetvector, endline), fileConn)
close(fileConn)
}

##########################################################################
######################## EXAMPLES ########################################
##########################################################################

#A math function
triA<-surfaceTriangles(seq(-1,1,len=30), seq(-1,1,len=30), function(x, y) (x^2 + y^2))
fv<-makefacet(triA)
makestl("C:/Users/LLPstudent/Desktop/HTMAA/week4/function1.stl", fv)

#Another math function
triA<-surfaceTriangles(seq(-1,1,len=30), seq(-1,1,len=30), function(x, y) (cos(y*4)+(y+1)*sin(x*4+2)))
fv<-makefacet(triA)
makestl("C:/Users/LLPstudent/Desktop/HTMAA/week4/function2.stl", fv)

#More math
triA<-surfaceTriangles(seq(-1,1,len=30), seq(-1,1,len=30), function(x, y) (cos(4*x*y)^3*sin(4*x*y)))
fv<-makefacet(triA)
makestl("C:/Users/LLPstudent/Desktop/HTMAA/week4/function3.stl", fv)

#And even more math
triA<-surfaceTriangles(seq(-1,1,len=30), seq(-1,1,len=30), function(x, y) (sin(abs(x*4)-abs(y*4))), color2 = "green")
fv<-makefacet(triA)
makestl("C:/Users/LLPstudent/Desktop/HTMAA/week4/function4.stl", fv)

#