Newtrat

[Lua] STL to OBJ

Apr 15th, 2016
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.26 KB | None | 0 0
  1. --[[
  2.     Convert ASCII STL file to OBJ (wavefront file) with optional coloring
  3.     V 1.0
  4. --]]
  5.  
  6. local version = "1.0"
  7.  
  8. print("Usage:")
  9. print("stl_to_obj.lua <stl_file> [<color>]")
  10. print("-----------")
  11. print("<color>: can be a color: red,green,blue,cyan,magenta,yellow")
  12. print("<color>: can be and RGB value R,G,B: 255,70,80")
  13.  
  14. --/////////////////////////////////////////////////////////////////
  15. -- input stl filename
  16. local stl_filename = arg[1]
  17. local filename = string.sub(stl_filename,1,-5)
  18.  
  19. print()
  20. print("Input file: "..stl_filename)
  21.  
  22. local color_rgb = {
  23.     ["red"] = {1.0,0,0},
  24.     ["green"] = {0,1.0,0},
  25.     ["blue"] = {0,0,1.0},
  26.     ["cyan"] = {0,1.0,1.0},
  27.     ["magenta"] = {1.0,0,1.0},
  28.     ["yellow"] = {1.0,1.0,0},
  29. }
  30.  
  31. local color = {}
  32. if arg and arg[2] then
  33.     if color_rgb[arg[2]] then
  34.         color = color_rgb[arg[2]]
  35.     else
  36.         local r,g,b = string.match(arg[2],"(%d+),(%d+),(%d+)")
  37.         color = {tonumber(r)/255,tonumber(g)/255,tonumber(b)/255}
  38.     end
  39.     print("Input color: "..arg[2])
  40. end
  41.  
  42.  
  43.  
  44.  
  45. -- obj filename
  46. local obj_filename = filename..".obj"
  47. print("Output file: "..obj_filename)
  48.  
  49. local t_vertices = {}
  50. local t_normals = {}
  51. local t_faces = {}
  52.  
  53. --/////////////////////////////////////////////////////////////////
  54. -- parse stl file
  55. local file_stl = io.open(stl_filename, "r")
  56.  
  57. local cur_face = {}
  58. local count = 0
  59. for line in file_stl:lines() do
  60.     if string.find(line, "^%s*facet normal") then
  61.         local x,y,z = string.match(line, "(%S+)%s(%S+)%s(%S+)$")
  62.         table.insert(cur_face, {tonumber(x),tonumber(y),tonumber(z)})
  63.     end
  64.     if string.find(line, "^%s*vertex") then
  65.         local x,y,z = string.match(line, "(%S+)%s(%S+)%s(%S+)$")
  66.         table.insert(cur_face, {tonumber(x),tonumber(y),tonumber(z)})
  67.         count = count + 1
  68.         if count == 3 then
  69.             table.insert(t_faces,cur_face)
  70.             cur_face = {}
  71.             count = 0
  72.         end
  73.     end
  74. end
  75. file_stl:close()
  76.  
  77. --/////////////////////////////////////////////////////////////////
  78. -- write mtl
  79. local mtl_filename = filename..".mtl"
  80. if #color ~= 0 then
  81.     print("Output mtl: "..mtl_filename)
  82.     local file = io.open(mtl_filename, "w")
  83.     file:write(
  84.         "# Color: "..arg[2].."\n"..
  85.         "newmtl color_"..arg[2].."\n"..
  86.         "Ka "..string.format("%f",color[1]).." "..string.format("%f",color[2]).." "..string.format("%f",color[3]).."\n"..
  87.         "Kd "..string.format("%f",color[1]).." "..string.format("%f",color[2]).." "..string.format("%f",color[3]).."\n"..
  88.         "Ks 0.000 0.000 0.000\n")
  89.     file:close()
  90. end
  91.  
  92. print()
  93.  
  94. --/////////////////////////////////////////////////////////////////
  95. -- write obj
  96. local file = io.open(obj_filename, "w")
  97.  
  98. file:write("#########################################\n")
  99. file:write("# Wavefront .obj file\n")
  100. file:write("# Created by: stl_to_obj.lua (v "..version..") / Author: Michael Lutz\n")
  101. file:write("# Date: "..os.date().."\n")
  102. file:write("#########################################\n\n")
  103.  
  104. if #color ~= 0 then
  105.     file:write("#########################################\n")
  106.     file:write("# MTL lib:\n\n")
  107.     file:write("mtllib "..mtl_filename.."\n\n")
  108. end
  109.  
  110. --/////////////////////////////////////////////////////////////////
  111. -- # List of Vertices
  112. file:write("#########################################\n")
  113. file:write("# List of vertices:\n\n")
  114.  
  115. for i,v in ipairs(t_faces) do
  116.     for i2=2,4 do
  117.         file:write("v "..string.format("%f",v[i2][1]).." "..string.format("%f",v[i2][2]).." "..string.format("%f",v[i2][3]).."\n")
  118.     end
  119. end
  120. file:write("\n")
  121.  
  122. --/////////////////////////////////////////////////////////////////
  123. --# Normals in (x,y,z) form; normals might not be unit.
  124. -- Normals are not needed since stl saves the triangles in counter clock anyways
  125. --file:write("\n# List of Normals\n\n")
  126. --for i,v in ipairs(t_faces) do
  127. --  file:write("vn "..string.format("%f",v[1][1]).." "..string.format("%f",v[1][2]).." "..string.format("%f",v[1][3]).."\n")
  128. --end
  129.  
  130. --/////////////////////////////////////////////////////////////////
  131. -- # Face Definitions (see below)
  132. file:write("#########################################\n")
  133. file:write("# Face definitions:\n\n")
  134.  
  135.  
  136. if #color ~= 0 then
  137.     file:write("usemtl color_"..arg[2].."\n\n")
  138. end
  139.  
  140. for i,v in ipairs(t_faces) do
  141.     local i2 = (i-1)*3
  142.     --file:write("f "..(i2+1).."//"..i.." "..(i2+2).."//"..i.." "..(i2+3).."//"..i.."\n")
  143.     file:write("f "..(i2+1).." "..(i2+2).." "..(i2+3).."\n")
  144. end
  145.  
  146. file:close()
Advertisement
Add Comment
Please, Sign In to add comment