-
Notifications
You must be signed in to change notification settings - Fork 22
/
makeanim.rb
71 lines (61 loc) · 1.75 KB
/
makeanim.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
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils
require 'open3'
def sh(*args)
output_buffer = ""
error_buffer = ""
res = Open3.popen3(*args) do |input, output, error, wait_thr|
set = [output, error]
while set.any?
o = select(set)
o[0].each do |io|
begin
data = io.read_nonblock(64)
if data && !data.empty?
output_buffer << data
error_buffer << data if io == error
else
io.close
set.delete(io)
end
rescue EOFError
io.close
set.delete(io)
end
end
[output_buffer, error_buffer].each do |buf|
buf.gsub!(/^.*\n/) do |m|
printf "%8s %s", Thread.current[:id], m
''
end
end
end
print output_buffer
print error_buffer
result = wait_thr.value
raise "Command failed" unless result.success?
end
end
mkdir_p 'anim'
length = 5.0
fps = 10.0
frames = (fps * length).floor
filenames = []
queue = Queue.new
workers = Array.new(16) { |i| Thread.new(i) { |n|
Thread.current[:id] = n
while job = queue.pop
sh *job
end
} }
frames.times do |i|
t = i / frames.to_f
filename = "anim/img%04d.png" % i
queue.push ['openscad', "-D$t=#{t}", '-o', filename, 'box.scad']
filenames << filename
end
workers.size.times { queue.push(nil) }
workers.each { |w| w.join }
sh 'convert', *filenames, '-delay', (1000 / fps).floor.to_s, '-layers', 'optimize', 'anim.gif'
# sh *%w{ convert anim.gif ( -clone 0--1 -background none +append -quantize transparent -colors 63 -unique-colors -write mpr:cmap +delete ) -map mpr:cmap anim_cmap.gif }