tracksperanto 1.7.4 → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +4 -0
- data/Manifest.txt +2 -0
- data/bin/tracksperanto +13 -7
- data/lib/export/syntheyes.rb +4 -4
- data/lib/import/shake_grammar/lexer.rb +4 -2
- data/lib/pipeline/base.rb +16 -3
- data/lib/tracksperanto.rb +4 -5
- data/lib/tracksperanto/ext_io.rb +3 -3
- data/lib/tracksperanto/progressive_io.rb +79 -0
- data/test/test_progressive_io.rb +119 -0
- metadata +5 -2
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -46,6 +46,7 @@ lib/tracksperanto/const_name.rb
|
|
46
46
|
lib/tracksperanto/ext_io.rb
|
47
47
|
lib/tracksperanto/format_detector.rb
|
48
48
|
lib/tracksperanto/keyframe.rb
|
49
|
+
lib/tracksperanto/progressive_io.rb
|
49
50
|
lib/tracksperanto/safety.rb
|
50
51
|
lib/tracksperanto/simple_export.rb
|
51
52
|
lib/tracksperanto/tracker.rb
|
@@ -129,6 +130,7 @@ test/test_const_name.rb
|
|
129
130
|
test/test_extio.rb
|
130
131
|
test/test_format_detector.rb
|
131
132
|
test/test_keyframe.rb
|
133
|
+
test/test_progressive_io.rb
|
132
134
|
test/test_simple_export.rb
|
133
135
|
test/test_tracker.rb
|
134
136
|
test/test_tracksperanto.rb
|
data/bin/tracksperanto
CHANGED
@@ -92,7 +92,6 @@ end
|
|
92
92
|
input_file = ARGV.pop
|
93
93
|
if !input_file
|
94
94
|
STDERR.puts "No input file provided - should be the last argument"
|
95
|
-
puts parser
|
96
95
|
exit(-1)
|
97
96
|
end
|
98
97
|
|
@@ -100,20 +99,26 @@ class Spinner
|
|
100
99
|
RING = ['|', '/', '-', '\\', '|', '/', '-', '\\']
|
101
100
|
|
102
101
|
def initialize
|
103
|
-
@counter = 0
|
104
|
-
@last_message_length = 0
|
102
|
+
@counter, @last_len = 0, 0
|
105
103
|
end
|
106
104
|
|
107
105
|
def spin(percent, msg)
|
108
106
|
current = RING[(@counter += 1) % RING.length]
|
109
107
|
output = " [%s %d%%]" % [current, percent]
|
110
|
-
STDOUT.write(output + "\r" * output.length)
|
108
|
+
STDOUT.write(output + ("\r" * output.length))
|
111
109
|
STDOUT.flush
|
110
|
+
@last_len = output.length
|
111
|
+
end
|
112
|
+
|
113
|
+
def finish(with_message = '')
|
114
|
+
STDOUT.write("\r" * @last_len.to_i)
|
115
|
+
STDOUT.flush
|
116
|
+
STDOUT.puts(with_message)
|
112
117
|
end
|
113
118
|
end
|
114
119
|
|
115
|
-
|
116
|
-
pipe
|
120
|
+
spinner = Spinner.new
|
121
|
+
pipe = Tracksperanto::Pipeline::Base.new(:progress_block => spinner.method(:spin).to_proc)
|
117
122
|
|
118
123
|
if sole_format
|
119
124
|
begin
|
@@ -137,4 +142,5 @@ pipe.run(input_file, :pix_w => width, :pix_h => height, :parser => reader_klass)
|
|
137
142
|
lerpm.enabled = lerp
|
138
143
|
len.min_length = length_gate
|
139
144
|
end
|
140
|
-
|
145
|
+
|
146
|
+
spinner.finish("Converted #{pipe.converted_points} trackers with #{pipe.converted_keyframes} keys")
|
data/lib/export/syntheyes.rb
CHANGED
@@ -25,7 +25,7 @@ class Tracksperanto::Export::SynthEyes < Tracksperanto::Export::Base
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def start_tracker_segment(tracker_name)
|
28
|
-
@
|
28
|
+
@last_registered_frame, @tracker_name = nil, tracker_name
|
29
29
|
end
|
30
30
|
|
31
31
|
def export_point(frame, abs_float_x, abs_float_y, float_residual)
|
@@ -38,14 +38,14 @@ class Tracksperanto::Export::SynthEyes < Tracksperanto::Export::Base
|
|
38
38
|
# It's very important that we provide an outcome code for Syntheyes. Regular keyframes get
|
39
39
|
# STATUS_STD, and after a gap we have to signal STATUS_REENABLE, otherwise this might bust solves
|
40
40
|
def get_outcome_code(frame)
|
41
|
-
outcome = if @
|
41
|
+
outcome = if @last_registered_frame.nil?
|
42
42
|
STATUS_KF
|
43
|
-
elsif @
|
43
|
+
elsif @last_registered_frame != (frame - 1)
|
44
44
|
STATUS_REENABLE
|
45
45
|
else
|
46
46
|
STATUS_STD
|
47
47
|
end
|
48
|
-
@
|
48
|
+
@last_registered_frame = frame
|
49
49
|
outcome
|
50
50
|
end
|
51
51
|
end
|
@@ -12,6 +12,8 @@ module Tracksperanto::ShakeGrammar
|
|
12
12
|
attr_reader :sentinel
|
13
13
|
|
14
14
|
STOP_TOKEN = :__stop #:nodoc:
|
15
|
+
MAX_BUFFER_SIZE = 32000
|
16
|
+
MAX_STACK_DEPTH = 127
|
15
17
|
|
16
18
|
# The first argument is the IO handle to the data of the Shake script.
|
17
19
|
# The second argument is a "sentinel" that is going to be passed
|
@@ -42,11 +44,11 @@ module Tracksperanto::ShakeGrammar
|
|
42
44
|
|
43
45
|
c = @io.read(1)
|
44
46
|
|
45
|
-
if @buf.length >
|
47
|
+
if @buf.length > MAX_BUFFER_SIZE # Wrong format and the buffer is filled up, bail
|
46
48
|
raise WrongInput, "Buffer overflow at 32K, this is definitely not a Shake script"
|
47
49
|
end
|
48
50
|
|
49
|
-
if @stack_depth >
|
51
|
+
if @stack_depth > MAX_STACK_DEPTH # Wrong format - parentheses overload
|
50
52
|
raise WrongInput, "Stack overflow at level 128, this is probably a LISP program uploaded by accident"
|
51
53
|
end
|
52
54
|
|
data/lib/pipeline/base.rb
CHANGED
@@ -13,6 +13,8 @@
|
|
13
13
|
# and setup outputs for all supported export formats.
|
14
14
|
class Tracksperanto::Pipeline::Base
|
15
15
|
|
16
|
+
include Tracksperanto::BlockInit
|
17
|
+
|
16
18
|
# How many points have been converted. In general, the pipeline does not preserve the parsed tracker objects
|
17
19
|
# after they have been exported
|
18
20
|
attr_reader :converted_points
|
@@ -83,16 +85,27 @@ class Tracksperanto::Pipeline::Base
|
|
83
85
|
# If a block is passed, the block will receive the percent complete and the last
|
84
86
|
# status message that you can pass back to the UI
|
85
87
|
def run_export(tracker_data_io, parser, processor)
|
86
|
-
@ios << tracker_data_io
|
87
|
-
|
88
88
|
points, keyframes, percent_complete = 0, 0, 0.0
|
89
89
|
|
90
90
|
yield(percent_complete, "Starting the parser") if block_given?
|
91
|
+
|
92
|
+
# Report progress from the parser
|
91
93
|
parser.progress_block = lambda do | message |
|
92
94
|
yield(percent_complete, message) if block_given?
|
93
95
|
end
|
94
96
|
|
95
|
-
|
97
|
+
# Wrap the input in a progressive IO
|
98
|
+
io_with_progress = Tracksperanto::ProgressiveIO.new(tracker_data_io)
|
99
|
+
@ios << io_with_progress
|
100
|
+
|
101
|
+
# Setup a lambda that will spy on the reader and update the percentage.
|
102
|
+
# We will only broadcast messages that come from the parser though (complementing it
|
103
|
+
# with a percentage)
|
104
|
+
io_with_progress.progress_block = lambda do | offset, of_total |
|
105
|
+
percent_complete = (50.0 / of_total) * offset
|
106
|
+
end
|
107
|
+
|
108
|
+
trackers = parser.parse(io_with_progress)
|
96
109
|
|
97
110
|
validate_trackers!(trackers)
|
98
111
|
|
data/lib/tracksperanto.rb
CHANGED
@@ -4,7 +4,7 @@ require 'tempfile'
|
|
4
4
|
|
5
5
|
module Tracksperanto
|
6
6
|
PATH = File.expand_path(File.dirname(__FILE__))
|
7
|
-
VERSION = '1.7.
|
7
|
+
VERSION = '1.7.5'
|
8
8
|
|
9
9
|
module Import; end
|
10
10
|
module Export; end
|
@@ -42,8 +42,7 @@ module Tracksperanto
|
|
42
42
|
# Case-insensitive search for an export module by name
|
43
43
|
def self.get_exporter(name)
|
44
44
|
exporters.each do | x |
|
45
|
-
|
46
|
-
return x if normalized_name == name.downcase
|
45
|
+
return x if x.const_name.downcase == name.downcase
|
47
46
|
end
|
48
47
|
|
49
48
|
raise NameError, "Unknown exporter #{name}"
|
@@ -52,8 +51,7 @@ module Tracksperanto
|
|
52
51
|
# Case-insensitive search for an export module by name
|
53
52
|
def self.get_importer(name)
|
54
53
|
importers.each do | x |
|
55
|
-
|
56
|
-
return x if normalized_name == name.downcase
|
54
|
+
return x if x.const_name.downcase == name.downcase
|
57
55
|
end
|
58
56
|
|
59
57
|
raise NameError, "Unknown importer #{name}"
|
@@ -70,6 +68,7 @@ end
|
|
70
68
|
tracker
|
71
69
|
format_detector
|
72
70
|
ext_io
|
71
|
+
progressive_io
|
73
72
|
simple_export
|
74
73
|
uv_coordinates
|
75
74
|
).each do | submodule |
|
data/lib/tracksperanto/ext_io.rb
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
# Many importers use this as a standard. This works like a wrapper for any
|
2
|
-
# IO object with a couple extra methods added
|
2
|
+
# IO object with a couple extra methods added.
|
3
3
|
class Tracksperanto::ExtIO < DelegateClass(IO)
|
4
4
|
def initialize(with)
|
5
5
|
__setobj__ with
|
6
6
|
end
|
7
7
|
|
8
8
|
def gets_and_strip
|
9
|
-
s =
|
9
|
+
s = gets
|
10
10
|
s ? s.strip : nil
|
11
11
|
end
|
12
12
|
|
13
13
|
def gets_non_empty
|
14
|
-
line =
|
14
|
+
line = gets
|
15
15
|
return nil if line.nil?
|
16
16
|
s = line.strip
|
17
17
|
return gets_non_empty if s.empty?
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Used for IO objects that need to report the current offset at each operation that changes the said offset
|
2
|
+
# (useful for building progress bars that report on a file read operation)
|
3
|
+
class Tracksperanto::ProgressiveIO < DelegateClass(IO)
|
4
|
+
|
5
|
+
# Should contain a block that accepts the current offset in bytes and the total size
|
6
|
+
attr_accessor :progress_block
|
7
|
+
|
8
|
+
# Get or set the total size of the contained IO. If the passed IO is a File object
|
9
|
+
# the size will be preset automatically
|
10
|
+
attr_accessor :total_size
|
11
|
+
|
12
|
+
def initialize(with_file)
|
13
|
+
__setobj__(with_file)
|
14
|
+
@total_size = with_file.stat.size if with_file.respond_to?(:stat)
|
15
|
+
end
|
16
|
+
|
17
|
+
def each(sep_string = $/, &blk)
|
18
|
+
# Report offset at each call of the iterator
|
19
|
+
result = super(sep_string) do | line |
|
20
|
+
yield(line)
|
21
|
+
notify_read
|
22
|
+
end
|
23
|
+
end
|
24
|
+
alias_method :each_line, :each
|
25
|
+
|
26
|
+
def each_byte(&blk)
|
27
|
+
# Report offset at each call of the iterator
|
28
|
+
super { |b| yield(b); notify_read }
|
29
|
+
end
|
30
|
+
|
31
|
+
def getc
|
32
|
+
returning(super) { notify_read }
|
33
|
+
end
|
34
|
+
|
35
|
+
def gets
|
36
|
+
returning(super) { notify_read }
|
37
|
+
end
|
38
|
+
|
39
|
+
def read(*a)
|
40
|
+
returning(super) { notify_read }
|
41
|
+
end
|
42
|
+
|
43
|
+
def readbytes(*a)
|
44
|
+
returning(super) { notify_read }
|
45
|
+
end
|
46
|
+
|
47
|
+
def readchar
|
48
|
+
returning(super) { notify_read }
|
49
|
+
end
|
50
|
+
|
51
|
+
def readline(*a)
|
52
|
+
returning(super) { notify_read }
|
53
|
+
end
|
54
|
+
|
55
|
+
def readlines(*a)
|
56
|
+
returning(super) { notify_read }
|
57
|
+
end
|
58
|
+
|
59
|
+
def seek(*a)
|
60
|
+
returning(super) { notify_read }
|
61
|
+
end
|
62
|
+
|
63
|
+
def ungetc(*a)
|
64
|
+
returning(super) { notify_read }
|
65
|
+
end
|
66
|
+
|
67
|
+
def pos=(p)
|
68
|
+
returning(super) { notify_read }
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def returning(r)
|
73
|
+
yield; r
|
74
|
+
end
|
75
|
+
|
76
|
+
def notify_read
|
77
|
+
@progress_block.call(pos, @total_size) if @progress_block
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TestProgressiveIO < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def e(s)
|
6
|
+
|
7
|
+
# Make a mock File object from a string
|
8
|
+
io = StringIO.new(s)
|
9
|
+
mock_stat = flexmock(:size => s.length)
|
10
|
+
flexmock(io).should_receive(:stat).and_return(mock_stat)
|
11
|
+
|
12
|
+
Tracksperanto::ProgressiveIO.new(io)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_each
|
16
|
+
io, messages = e("Mary\nHad\nA little\nLamb"), []
|
17
|
+
|
18
|
+
io.progress_block = lambda do | offset, total |
|
19
|
+
messages.push([offset, total])
|
20
|
+
end
|
21
|
+
|
22
|
+
lines = []
|
23
|
+
io.each {|line| lines.push(line) }
|
24
|
+
assert_equal ["Mary\n", "Had\n", "A little\n", "Lamb"], lines
|
25
|
+
assert_equal [[5, 22], [9, 22], [18, 22], [22, 22]], messages
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_each_byte
|
29
|
+
io, messages = e("123"), []
|
30
|
+
|
31
|
+
io.progress_block = lambda do | offset, total |
|
32
|
+
messages.push([offset, total])
|
33
|
+
end
|
34
|
+
|
35
|
+
bytes = []
|
36
|
+
io.each_byte{|s| bytes << s }
|
37
|
+
assert_equal [49, 50, 51], bytes
|
38
|
+
assert_equal [[1, 3], [2, 3], [3, 3]], messages
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_getc
|
42
|
+
io = e("123")
|
43
|
+
io.progress_block = lambda do | offset, total |
|
44
|
+
assert_equal [1, 3], [offset, total]
|
45
|
+
end
|
46
|
+
assert_equal 49, io.getc
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_gets
|
50
|
+
io = e("Mary\nHad\nA little\nLamb")
|
51
|
+
io.progress_block = lambda do | offset, total |
|
52
|
+
assert_equal [5, 22], [offset, total]
|
53
|
+
end
|
54
|
+
assert_equal "Mary\n", io.gets
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_read
|
58
|
+
io = e("Mary\nHad\nA little\nLamb")
|
59
|
+
io.progress_block = lambda do | offset, total |
|
60
|
+
assert_equal [15, 22], [offset, total]
|
61
|
+
end
|
62
|
+
assert_equal "Mary\nHad\nA litt", io.read(15)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_readchar
|
66
|
+
io = e("123")
|
67
|
+
io.progress_block = lambda do | offset, total |
|
68
|
+
assert_equal [1, 3], [offset, total]
|
69
|
+
end
|
70
|
+
assert_equal 49, io.readchar
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_readline
|
74
|
+
io = e("Mary\nHad\nA little\nLamb")
|
75
|
+
io.progress_block = lambda do | offset, total |
|
76
|
+
assert_equal [5, 22], [offset, total]
|
77
|
+
end
|
78
|
+
assert_equal "Mary\n", io.readline
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_readlines
|
82
|
+
io = e("Mary\nHad\nA little\nLamb")
|
83
|
+
m = []
|
84
|
+
io.progress_block = lambda do | offset, total |
|
85
|
+
m.push([offset, total])
|
86
|
+
end
|
87
|
+
|
88
|
+
assert_equal ["Mary\n", "Had\n", "A little\n", "Lamb"], io.readlines
|
89
|
+
assert_equal [[22, 22]], m
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_seek
|
93
|
+
io = e("Mary\nHad\nA little\nLamb")
|
94
|
+
io.progress_block = lambda do | offset, total |
|
95
|
+
assert_equal [6, 22], [offset, total]
|
96
|
+
end
|
97
|
+
io.seek(6)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_ungetc
|
101
|
+
io = e("Mary\nHad\nA little\nLamb")
|
102
|
+
m = []
|
103
|
+
io.progress_block = lambda do | offset, total |
|
104
|
+
m.push([offset, total])
|
105
|
+
end
|
106
|
+
|
107
|
+
io.getc
|
108
|
+
io.ungetc(2)
|
109
|
+
assert_equal [[1, 22], [0, 22]], m
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_poseq
|
113
|
+
io = e("Mary\nHad\nA little\nLamb")
|
114
|
+
io.progress_block = lambda do | offset, total |
|
115
|
+
assert_equal [2, 22], [offset, total]
|
116
|
+
end
|
117
|
+
io.pos = 2
|
118
|
+
end
|
119
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tracksperanto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-17 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- lib/tracksperanto/ext_io.rb
|
94
94
|
- lib/tracksperanto/format_detector.rb
|
95
95
|
- lib/tracksperanto/keyframe.rb
|
96
|
+
- lib/tracksperanto/progressive_io.rb
|
96
97
|
- lib/tracksperanto/safety.rb
|
97
98
|
- lib/tracksperanto/simple_export.rb
|
98
99
|
- lib/tracksperanto/tracker.rb
|
@@ -176,6 +177,7 @@ files:
|
|
176
177
|
- test/test_extio.rb
|
177
178
|
- test/test_format_detector.rb
|
178
179
|
- test/test_keyframe.rb
|
180
|
+
- test/test_progressive_io.rb
|
179
181
|
- test/test_simple_export.rb
|
180
182
|
- test/test_tracker.rb
|
181
183
|
- test/test_tracksperanto.rb
|
@@ -244,6 +246,7 @@ test_files:
|
|
244
246
|
- test/test_extio.rb
|
245
247
|
- test/test_format_detector.rb
|
246
248
|
- test/test_keyframe.rb
|
249
|
+
- test/test_progressive_io.rb
|
247
250
|
- test/test_simple_export.rb
|
248
251
|
- test/test_tracker.rb
|
249
252
|
- test/test_tracksperanto.rb
|