-
Notifications
You must be signed in to change notification settings - Fork 1
/
generate_missing_stl.rb
executable file
·168 lines (140 loc) · 5.95 KB
/
generate_missing_stl.rb
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env ruby
#
# generate_missing_stl.rb -- Walk a directory structure & export missing STL files with SketchUp
#
# Developed in order to generate the missing STL files in SparkFun's
# 3D Model repository for which source SketchUp `.skp` files exist.
#
# Written to work with SketchUp 2015, `sketchup-stl` extension & Mac OS X.
#
#
# Note: You will need to babysit this script when running it because
# exporting seems to frequently fail non-deterministically with
# either segfaults or Ruby errors. Eventually re-running the
# automation enough times generated all the files for our purposes.
#
#
# Usage:
#
# (1) The script can be used to scan a directory hierarchy to list
# `.skp` files for which no `.stl` file exists (searched
# according to directory layout used in SparkFun repository).
#
# (2) The script can be used to generate the missing `.stl` files by
# automating SketchUp. Rather than running as a plugin (which
# could be investigated to see if it's more reliable) this script
# automates SketchUp itself by being run as a startup script.
#
# As arguments cannot be supplied to a startup script as part of
# the command line, the directory root to be scanned is supplied
# in the `STL_GENERATE_ROOT` environment variable. (If this
# environment variable is set manually then this script can also
# be started via `load '/<path>/generate_missing_stl.rb'` in the
# SketchUpRuby console.)
#
# In addition, a "dummy"/empty `.skp` file needs to be present
# and the file path supplied to the command line for opening,
# otherwise the startup script is not executed.
#
# An example full command line to begin the automation is:
#
# STL_GENERATE_ROOT=/<path>/sparkfun-github/3D_Models/production_parts/ /<path>/SketchUp\ 2015/SketchUp.app/Contents/MacOS/SketchUp -RubyStartup /<path>/generate_missing_stl.rb /<path>/dummy.skp
#
# If a splash screen is displayed on opening of the SketchUp app
# then it needs to be configured to not display or AppleScript
# needs to be used to close it:
#
# STL_GENERATE_ROOT=/<path>/sparkfun-github/3D_Models/production_parts/ /<path>/SketchUp\ 2015/SketchUp.app/Contents/MacOS/SketchUp -RubyStartup /<path>/generate_missing_stl.rb /<path>/dummy.skp & sleep 4; osascript -e 'activate application "SketchUp"' -e 'tell application "System Events"' -e 'key code 36' -e 'end tell'
#
# A limit of `BATCH_SIZE` exports are attempted per run of the
# script in order to reduce chances of a "runaway" script. This
# value can be increased if desired.
#
#
# Troubleshooting:
#
# For reasons unknown, it seems a delay is needed between opening a
# model and exporting it when multiple models are being exported.
#
# If this delay is not long enough the segfault and Ruby errors
# mentioned above seem to be more likely to occur. If required, this
# delay can be increased further.
#
# If a Ruby error occurs and is caught, the empty/partial/incorrectly
# exported `.stl` file will be renamed to have a `bad.` prefix in
# order to allow another export attempt to be tried without having to
# delete the bad file.
#
# IF A SEGFAULT OCCURS YOU MAY NEED TO DELETE THE LAST LISTED FILE
# LOGGED AS "Exporting :". If you do not, a partially exported file
# may exist and this will prevent another attempt at export.
#
require 'FileUtils'
within_sketchup = true
begin
require 'SketchUp'
rescue LoadError
within_sketchup = false
end
directory_root = ARGV[0] || ENV["STL_GENERATE_ROOT"]
puts "Scanning root: " + directory_root
puts ""
# Note: Case-insensitive file systems mean the case of the filepath
# logged may not match the case of the path on the disk.
BATCH_SIZE = 20
batch_count = 0
if within_sketchup
# Can help debugging but also messes with logging due to inconsistent print/puts behaviour.
#Sketchup.send_action "showRubyPanel:"
end
Dir.glob(File.join(directory_root, "**/*.skp")) {
|filepath|
base_directory = File.dirname(filepath)
base_name = File.basename(filepath, ".skp")
# Note: SparkFun repository stores the matching `.stl` file in one of two possible locations.
exported_stl_filepath_style_one = File.join(base_directory, base_name + ".stl") # In same directory
exported_stl_filepath_style_two = File.join(File.dirname(base_directory), "stl", base_name + ".stl") # In sibling directory
next if base_name.start_with? "AutoSave_" # TODO: Log this?
next if base_name.include? " - Copy"
if [exported_stl_filepath_style_one,
exported_stl_filepath_style_two].any? {|export_filepath| File.exist? export_filepath }
# TODO: Log existing files found?
else
# Determine what directory to export the model into, based on the
# directory naming convention used for the `.skp` file.
export_directory = base_directory
if File.basename(base_directory) == "skp"
# Export to `stl` sibling directory
export_directory = File.join(File.dirname(export_directory), "stl")
end
export_filepath = File.join(export_directory, base_name + ".stl")
# Do the actual export
if within_sketchup
print "Found: " + filepath
print " Exporting: " + export_filepath
Sketchup.open_file filepath
FileUtils.mkdir_p export_directory
sleep 5 # Note: Increasing this delay may increase reliability at the cost of longer runtime.
begin
CommunityExtensions::STL::Exporter.export(export_filepath)
print " Exported."
rescue
print " Error exporting: " + export_filepath
bad_export_filepath = File.join(export_directory, "bad." + base_name + ".stl")
File.rename export_filepath, bad_export_filepath
print " Bad export renamed: " + bad_export_filepath
end
sleep 1
Sketchup.send_action('performClose:')
sleep 3
batch_count += 1
if ((batch_count % BATCH_SIZE) == 0)
print "Batch limit reached."
break
end
else
puts "Found: " + filepath
end
end
}
print "Done."