-
Notifications
You must be signed in to change notification settings - Fork 0
/
export.py
135 lines (115 loc) · 4.63 KB
/
export.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import os
import subprocess
import sys
import tempfile
if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "?":
print("Usage: python export.py <filename.scad> [fileType]\n")
print("This script searches for \"module export()\" and individually renders and exports each item in it.")
print("Each item is expected to be on its own line. The file name will be the comment on the same line, or the module call if no comment exists.")
print("All files will be put in a folder with the same name as the scad file it's created from.")
print("\nExample:\n")
print("ExampleFile.scad")
print("module export() {\n cube(10);\n sphere(5); //Ball\n}\n")
print("\"python export.py ExampleFile.scad\" will generate a folder named \"ExampleFile exported\", and will contain the files \"cube.stl\" and \"Ball.stl\"")
sys.exit()
scadFileName = sys.argv[1]
fileType = "stl"
if len(sys.argv) >= 3:
fileType = sys.argv[2]
path = os.path.abspath(scadFileName)
endofpath = max(path.rfind("/"), path.rfind("\\"))+1
path = path[:endofpath]
folder = path + scadFileName[:scadFileName.rfind(".")] + " exported"
tempdir = tempfile.gettempdir()
lines = [""]
exportStart = -1
exportEnd = -1
def readFile(fileName):
global exportStart
global exportEnd
global lines
bracketCount = 0
#read file contents
fileIn = open(fileName, "r")
lines = fileIn.read().splitlines()
fileIn.close()
lines = lines + ["", "module ____single(index) {", "\tchildren(index);", "}"]
#fix relative imports
for i in range(len(lines)):
indexStart = -1
indexEnd = -1
if "use" in lines[i] or "include" in lines[i]:
indexStart = lines[i].find("<")+1
indexEnd = lines[i].find(">", indexStart)
if "import" in lines[i]:
indexStart = lines[i].find("\"")+1
indexEnd = lines[i].find("\"", indexStart)
if indexStart >= 0 and indexEnd >= 0:
lines[i] = lines[i][:indexStart] + os.path.abspath(lines[i][indexStart:indexEnd]) + lines[i][indexEnd:]
if "module export()" in lines[i]:
index = lines[i].find("module export()")+14
lines[i] = lines[i][:index] + "index) ____single(index" + lines[i][index:]
#search for "module export()" and determine module size
for i in range(len(lines)):
if exportStart == -1 and "module export(index)" in lines[i]:
if "{" in lines[i]:
exportStart = i
elif "{" in lines[i+1]:
exportStart = i+1
if exportStart != -1 and exportEnd == -1:
for c in lines[i]:
if c == "{":
bracketCount += 1
if c == "}":
bracketCount -= 1
if bracketCount <= 0:
exportEnd = i
return
def findFileName(string):
#if a comment exists, use that as the file name
if "//" in string:
i = string.rfind("//")+2
return string[i:]
#if no comment exists, use the module name as the file name
#this has the potential to overwrite previous files in this batch
bracket = string.rfind("(")
endWord = -1
startWord = -1
for i in range(bracket-1, -1, -1):
if (string[i] != " "):
endWord = i
break
for i in range(endWord-1, -1, -1):
if (i == 0 or string[i] == " " or string[i] == "\t"):
startWord = i+1
break
if startWord != -1 and endWord != -1:
return string[startWord:endWord+1]
def compileRunSCAD():
#create modified version of original
modified = open(os.path.join(tempdir, "modified.scad"), "w")
modified.write("\n".join(lines))
modified.flush()
modified.close()
#create temp scad file
file = open(os.path.join(tempdir, "temp.scad"), "w")
file.write("use <" + os.path.join(tempdir, "modified.scad") + ">")
file.write("\nindex = 0;\nexport(index);")
file.flush()
file.close()
index = 0
#for each module called in export(), create a temp scad file and call it at the end
for i in range(exportStart + 1, exportEnd):
if ";" in lines[i]:
name = findFileName(lines[i])
print("Generating " + name + ".stl")
#export stl file
subprocess.run(["openscad", "-o", os.path.join(folder, name) + "." + fileType, "-D", "index = " + str(index), os.path.join(tempdir, "temp.scad")])
index += 1
#cleanup temp files
os.remove(os.path.join(tempdir, "modified.scad"))
os.remove(os.path.join(tempdir, "temp.scad"))
readFile(scadFileName)
if not os.path.exists(folder):
os.mkdir(folder)
compileRunSCAD()