tracksperanto 3.5.7 → 3.5.8
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/Gemfile +2 -2
- data/lib/import/flame_stabilizer.rb +0 -5
- data/lib/import/match_mover.rb +20 -8
- data/lib/import/nuke_script.rb +1 -1
- data/lib/import/shake_grammar/lexer.rb +7 -8
- data/lib/tracksperanto.rb +1 -1
- data/lib/tracksperanto/blacklist.rb +1 -1
- data/test/import/test_match_mover_import.rb +33 -16
- data/test/test_blacklist.rb +1 -0
- data/tracksperanto.gemspec +8 -8
- metadata +10 -10
data/Gemfile
CHANGED
|
@@ -55,11 +55,6 @@ class Tracksperanto::Import::FlameStabilizer < Tracksperanto::Import::Base
|
|
|
55
55
|
class StabilizerParser < FlameChannelParser::Parser
|
|
56
56
|
USEFUL_CHANNELS = %w( /shift/x /shift/y /ref/x /ref/y ).map(&Regexp.method(:new))
|
|
57
57
|
|
|
58
|
-
# This method tells the importer whether a channel that has been found in the source
|
|
59
|
-
# setup is needed. If that method returns ++false++ the channel will be discarded and not
|
|
60
|
-
# kept in memory. Should you need to write a module that scavenges other Flame animation channels
|
|
61
|
-
# inherit from this class and rewrite this method to either return +true+ always (then all the channels
|
|
62
|
-
# will be recovered) or to return +true+ only for channels that you actually need.
|
|
63
58
|
def channel_is_useful?(channel_name)
|
|
64
59
|
USEFUL_CHANNELS.any?{|e| channel_name =~ e }
|
|
65
60
|
end
|
data/lib/import/match_mover.rb
CHANGED
|
@@ -15,6 +15,7 @@ class Tracksperanto::Import::MatchMover < Tracksperanto::Import::Base
|
|
|
15
15
|
|
|
16
16
|
def each
|
|
17
17
|
detect_format(@io)
|
|
18
|
+
raise "No tracker data after detecting format" if @io.eof?
|
|
18
19
|
extract_trackers(@io) { |t| yield(t) }
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -35,6 +36,13 @@ class Tracksperanto::Import::MatchMover < Tracksperanto::Import::Base
|
|
|
35
36
|
# as multiline, so we will need to succesively scan until we find our line that contains the dimensions
|
|
36
37
|
frame_steps_re = /b\( (\d+) (\d+) (\d+) \)/ # b( 0 293 1 )
|
|
37
38
|
until @first_frame_of_sequence
|
|
39
|
+
# There was nothing fetched, so we just assume the first frame is 0.
|
|
40
|
+
# Or this line contained "}" which terminates the imageSequence block.
|
|
41
|
+
if last_line.nil? || last_line.include?('}')
|
|
42
|
+
@first_frame_of_sequence = 0
|
|
43
|
+
return
|
|
44
|
+
end
|
|
45
|
+
|
|
38
46
|
digit_groups = last_line.scan(frame_steps_re).flatten
|
|
39
47
|
if digit_groups.any?
|
|
40
48
|
@first_frame_of_sequence, length, frame_step = digit_groups.map{|e| e.to_i }
|
|
@@ -42,7 +50,6 @@ class Tracksperanto::Import::MatchMover < Tracksperanto::Import::Base
|
|
|
42
50
|
end
|
|
43
51
|
last_line = io.gets
|
|
44
52
|
end
|
|
45
|
-
|
|
46
53
|
raise "Cannot detect the start frame of the sequence"
|
|
47
54
|
end
|
|
48
55
|
|
|
@@ -64,21 +71,26 @@ class Tracksperanto::Import::MatchMover < Tracksperanto::Import::Base
|
|
|
64
71
|
raise "Track didn't close"
|
|
65
72
|
end
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
FLOAT_PATTERN = /[\-\d\.]+/
|
|
75
|
+
LINE_PATTERN = /(\d+)\s+(#{FLOAT_PATTERN})\s+(#{FLOAT_PATTERN})/
|
|
68
76
|
|
|
69
77
|
def extract_key(line)
|
|
70
|
-
frame, x, y
|
|
78
|
+
frame, x, y = line.scan(LINE_PATTERN).flatten
|
|
71
79
|
Tracksperanto::Keyframe.new(
|
|
72
80
|
:frame => (frame.to_i - @first_frame_of_sequence),
|
|
73
81
|
:abs_x => x,
|
|
74
82
|
:abs_y => @height - y.to_f, # Top-left in MM
|
|
75
|
-
:residual => extract_residual(
|
|
83
|
+
:residual => extract_residual(line)
|
|
76
84
|
)
|
|
77
85
|
end
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
RESIDUAL_SEGMENT = /p[\*\+]\(\s+?(#{FLOAT_PATTERN})\s+?\)/
|
|
88
|
+
|
|
89
|
+
def extract_residual(line)
|
|
90
|
+
if line =~ RESIDUAL_SEGMENT
|
|
91
|
+
1- $1.to_f
|
|
92
|
+
else
|
|
93
|
+
0
|
|
94
|
+
end
|
|
83
95
|
end
|
|
84
96
|
end
|
data/lib/import/nuke_script.rb
CHANGED
|
@@ -28,7 +28,7 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
|
|
|
28
28
|
parser.add_node_handler_class(CornerPin2D)
|
|
29
29
|
parser.add_node_handler_class(Transform)
|
|
30
30
|
|
|
31
|
-
parser.parse(@io) do | node |
|
|
31
|
+
parser.parse(Bychar.wrap(@io)) do | node |
|
|
32
32
|
node.trackers.each do | t |
|
|
33
33
|
report_progress("Scavenging tracker #{t.name}")
|
|
34
34
|
yield t
|
|
@@ -25,17 +25,15 @@ module Tracksperanto::ShakeGrammar
|
|
|
25
25
|
# You can use the sentinel to collect data from child nodes for example.
|
|
26
26
|
def initialize(with_io, sentinel = nil, limit_to_one_stmt = false, stack_depth = 0)
|
|
27
27
|
# We parse byte by byte, but reading byte by byte is very slow. We therefore use a buffering reader
|
|
28
|
-
# that will cache in chunks, and then read from there byte by byte.
|
|
28
|
+
# that will cache in chunks, and then read from there byte by byte.
|
|
29
|
+
# This yields a substantial speedup (4.9 seconds for the test
|
|
29
30
|
# as opposed to 7.9 without this). We do check for the proper class only once so that when we use nested lexers
|
|
30
31
|
# we only wrap the passed IO once, and only if necessary.
|
|
31
|
-
with_io = Bychar.wrap(with_io) unless with_io.respond_to?(:read_one_char
|
|
32
|
+
with_io = Bychar.wrap(with_io) unless with_io.respond_to?(:read_one_char)
|
|
32
33
|
@io, @stack, @buf, @sentinel, @limit_to_one_stmt, @stack_depth = with_io, [], '', sentinel, limit_to_one_stmt, stack_depth
|
|
33
34
|
|
|
34
35
|
catch(STOP_TOKEN) do
|
|
35
|
-
|
|
36
|
-
loop { parse }
|
|
37
|
-
rescue Bychar::EOF
|
|
38
|
-
end
|
|
36
|
+
loop { parse }
|
|
39
37
|
end
|
|
40
38
|
|
|
41
39
|
@in_comment ? consume_comment! : consume_atom!
|
|
@@ -54,8 +52,6 @@ module Tracksperanto::ShakeGrammar
|
|
|
54
52
|
|
|
55
53
|
def parse
|
|
56
54
|
|
|
57
|
-
c = @io.read_one_char!
|
|
58
|
-
|
|
59
55
|
if @buf.length > MAX_BUFFER_SIZE # Wrong format and the buffer is filled up, bail
|
|
60
56
|
raise WrongInputError, "Atom buffer overflow at #{MAX_BUFFER_SIZE} bytes, this is definitely not a Shake script"
|
|
61
57
|
end
|
|
@@ -64,6 +60,9 @@ module Tracksperanto::ShakeGrammar
|
|
|
64
60
|
raise WrongInputError, "Stack overflow at level #{MAX_STACK_DEPTH}, this is probably a LISP program uploaded by accident"
|
|
65
61
|
end
|
|
66
62
|
|
|
63
|
+
c = @io.read_one_char
|
|
64
|
+
throw :__stop if c.nil? # IO has run out
|
|
65
|
+
|
|
67
66
|
if c == '/' && (@buf[-1].chr rescue nil) == '/' # Comment start
|
|
68
67
|
# If some other data from this line has been accumulated we first consume that
|
|
69
68
|
@buf = @buf[0..-2] # everything except the opening slash of the comment
|
data/lib/tracksperanto.rb
CHANGED
|
@@ -18,7 +18,7 @@ class Tracksperanto::Blacklist
|
|
|
18
18
|
/\.(r3d)$/ => 'Tracksperanto is not a tracking application, it converts tracks. We do not support RAW file formats.',
|
|
19
19
|
/\.(dpx|tif(f?)|jp(e?)g|png|gif|tga)$/ => 'Tracksperanto is not a tracking application, it converts tracks. We do not support image file formats.',
|
|
20
20
|
'.sni' => 'We cannot read binary SynthEyes scene files. Export your tracks as one of the supported formats.',
|
|
21
|
-
/\.(pfb|pfmp)/ => 'We cannot directly open PFTrack projects, export .2dt files instead',
|
|
21
|
+
/\.(pfb|pfmp|ptp)/ => 'We cannot directly open PFTrack projects, export .2dt files instead',
|
|
22
22
|
'.mmf' => 'We cannot directly open MatchMover projects, please export your tracks as .rz2 instead',
|
|
23
23
|
/\.(doc(x?)|xls(x?)|ppt(x?))/ => 'You really think we can process Microsoft Office files? You need a drink.',
|
|
24
24
|
/\.(abc|fbx)$/ => 'We cannot import 3D scenes such as Alembic or FBX.',
|
|
@@ -3,12 +3,6 @@ require File.expand_path(File.dirname(__FILE__)) + '/../helper'
|
|
|
3
3
|
|
|
4
4
|
class MatchMoverImportTest < Test::Unit::TestCase
|
|
5
5
|
DELTA = 0.01
|
|
6
|
-
|
|
7
|
-
P = File.dirname(__FILE__) + '/samples/match_mover/kipPointsMatchmover.rz2'
|
|
8
|
-
P2 = File.dirname(__FILE__) + '/samples/match_mover/NonSequentialMatchmoverPoints.rz2'
|
|
9
|
-
P3 = File.dirname(__FILE__) + '/samples/match_mover/cha_171_1020_atb_v001.rz2'
|
|
10
|
-
P4 = File.dirname(__FILE__) + '/samples/match_mover/2dtracks.rz2'
|
|
11
|
-
|
|
12
6
|
def test_introspects_properly
|
|
13
7
|
i = Tracksperanto::Import::MatchMover
|
|
14
8
|
assert_equal "MatchMover REALVIZ Ascii Point Tracks .rz2 file", i.human_name
|
|
@@ -16,7 +10,7 @@ class MatchMoverImportTest < Test::Unit::TestCase
|
|
|
16
10
|
end
|
|
17
11
|
|
|
18
12
|
def test_parsing_with_non_sequential_keyframes
|
|
19
|
-
fixture = File.open(
|
|
13
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/match_mover/NonSequentialMatchmoverPoints.rz2')
|
|
20
14
|
|
|
21
15
|
parser = Tracksperanto::Import::MatchMover.new(:io => fixture)
|
|
22
16
|
trackers = parser.to_a
|
|
@@ -25,7 +19,7 @@ class MatchMoverImportTest < Test::Unit::TestCase
|
|
|
25
19
|
end
|
|
26
20
|
|
|
27
21
|
def test_parsing_case_nil_exception
|
|
28
|
-
fixture = File.open(
|
|
22
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/match_mover/cha_171_1020_atb_v001.rz2')
|
|
29
23
|
|
|
30
24
|
parser = Tracksperanto::Import::MatchMover.new(:io => fixture)
|
|
31
25
|
trackers = parser.to_a
|
|
@@ -33,7 +27,7 @@ class MatchMoverImportTest < Test::Unit::TestCase
|
|
|
33
27
|
end
|
|
34
28
|
|
|
35
29
|
def test_parsing_from_matchmover
|
|
36
|
-
fixture = File.open(
|
|
30
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/match_mover/kipPointsMatchmover.rz2')
|
|
37
31
|
|
|
38
32
|
parser = Tracksperanto::Import::MatchMover.new(:io => fixture)
|
|
39
33
|
trackers = parser.to_a
|
|
@@ -51,17 +45,17 @@ class MatchMoverImportTest < Test::Unit::TestCase
|
|
|
51
45
|
assert_equal 0, first_kf.frame
|
|
52
46
|
assert_in_delta 649.523, first_kf.abs_x, DELTA
|
|
53
47
|
assert_in_delta 656.071, first_kf.abs_y, DELTA
|
|
54
|
-
assert_in_delta 0.
|
|
48
|
+
assert_in_delta 0.0, first_kf.residual, DELTA
|
|
55
49
|
|
|
56
|
-
last_kf = first_t[-
|
|
57
|
-
assert_equal
|
|
58
|
-
assert_in_delta
|
|
59
|
-
assert_in_delta
|
|
50
|
+
last_kf = first_t[-2]
|
|
51
|
+
assert_equal 129, last_kf.frame
|
|
52
|
+
assert_in_delta 598.273, last_kf.abs_x, DELTA
|
|
53
|
+
assert_in_delta 367.103, last_kf.abs_y, DELTA
|
|
60
54
|
assert_in_delta 0.027457, last_kf.residual, DELTA
|
|
61
55
|
end
|
|
62
56
|
|
|
63
57
|
def test_parsing_from_matchmover_with_multiline_sequence_path
|
|
64
|
-
fixture = File.open(
|
|
58
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/match_mover/2dtracks.rz2')
|
|
65
59
|
|
|
66
60
|
parser = Tracksperanto::Import::MatchMover.new(:io => fixture)
|
|
67
61
|
trackers = parser.to_a
|
|
@@ -79,6 +73,29 @@ class MatchMoverImportTest < Test::Unit::TestCase
|
|
|
79
73
|
assert_equal 119, first_kf.frame
|
|
80
74
|
assert_in_delta 10.715, first_kf.abs_x, DELTA
|
|
81
75
|
assert_in_delta 461.36, first_kf.abs_y, DELTA
|
|
82
|
-
assert_in_delta 0.
|
|
76
|
+
assert_in_delta 0.0, first_kf.residual, DELTA
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_parsing_from_file_with_shortened_sequence_format
|
|
80
|
+
fixture = File.open(File.dirname(__FILE__) + '/samples/match_mover/EP_1000_head_trackers_v002.rz2')
|
|
81
|
+
|
|
82
|
+
parser = Tracksperanto::Import::MatchMover.new(:io => fixture)
|
|
83
|
+
trackers = parser.to_a
|
|
84
|
+
|
|
85
|
+
assert_equal 714, parser.width
|
|
86
|
+
assert_equal 480, parser.height
|
|
87
|
+
|
|
88
|
+
assert_equal 7, trackers.length
|
|
89
|
+
|
|
90
|
+
first_t = trackers[0]
|
|
91
|
+
assert_equal "Tracker0002", first_t.name
|
|
92
|
+
assert_equal 130, first_t.length
|
|
93
|
+
first_kf = first_t[0]
|
|
94
|
+
|
|
95
|
+
assert_equal 1017, first_kf.frame
|
|
96
|
+
assert_in_delta 357.89, first_kf.abs_x, DELTA
|
|
97
|
+
assert_in_delta 371.96, first_kf.abs_y, DELTA
|
|
98
|
+
assert_in_delta 0.0, first_kf.residual, DELTA
|
|
83
99
|
end
|
|
100
|
+
|
|
84
101
|
end
|
data/test/test_blacklist.rb
CHANGED
data/tracksperanto.gemspec
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{tracksperanto}
|
|
8
|
-
s.version = "3.5.
|
|
8
|
+
s.version = "3.5.8"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Julik Tarkhanov"]
|
|
12
|
-
s.date = %q{
|
|
12
|
+
s.date = %q{2015-06-04}
|
|
13
13
|
s.default_executable = %q{tracksperanto}
|
|
14
14
|
s.description = %q{Converts 2D track exports between different apps like Flame, MatchMover, PFTrack...}
|
|
15
15
|
s.email = %q{me@julik.nl}
|
|
@@ -221,8 +221,8 @@ Gem::Specification.new do |s|
|
|
|
221
221
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
222
222
|
s.add_runtime_dependency(%q<bundler>, [">= 0"])
|
|
223
223
|
s.add_runtime_dependency(%q<obuf>, ["~> 1.1"])
|
|
224
|
-
s.add_runtime_dependency(%q<tickly>, ["~> 2.1.
|
|
225
|
-
s.add_runtime_dependency(%q<bychar>, ["~>
|
|
224
|
+
s.add_runtime_dependency(%q<tickly>, ["~> 2.1.6"])
|
|
225
|
+
s.add_runtime_dependency(%q<bychar>, ["~> 3"])
|
|
226
226
|
s.add_runtime_dependency(%q<progressive_io>, ["~> 1.0"])
|
|
227
227
|
s.add_runtime_dependency(%q<flame_channel_parser>, ["~> 4.0"])
|
|
228
228
|
s.add_runtime_dependency(%q<progressbar>, ["= 0.10.0"])
|
|
@@ -237,8 +237,8 @@ Gem::Specification.new do |s|
|
|
|
237
237
|
else
|
|
238
238
|
s.add_dependency(%q<bundler>, [">= 0"])
|
|
239
239
|
s.add_dependency(%q<obuf>, ["~> 1.1"])
|
|
240
|
-
s.add_dependency(%q<tickly>, ["~> 2.1.
|
|
241
|
-
s.add_dependency(%q<bychar>, ["~>
|
|
240
|
+
s.add_dependency(%q<tickly>, ["~> 2.1.6"])
|
|
241
|
+
s.add_dependency(%q<bychar>, ["~> 3"])
|
|
242
242
|
s.add_dependency(%q<progressive_io>, ["~> 1.0"])
|
|
243
243
|
s.add_dependency(%q<flame_channel_parser>, ["~> 4.0"])
|
|
244
244
|
s.add_dependency(%q<progressbar>, ["= 0.10.0"])
|
|
@@ -254,8 +254,8 @@ Gem::Specification.new do |s|
|
|
|
254
254
|
else
|
|
255
255
|
s.add_dependency(%q<bundler>, [">= 0"])
|
|
256
256
|
s.add_dependency(%q<obuf>, ["~> 1.1"])
|
|
257
|
-
s.add_dependency(%q<tickly>, ["~> 2.1.
|
|
258
|
-
s.add_dependency(%q<bychar>, ["~>
|
|
257
|
+
s.add_dependency(%q<tickly>, ["~> 2.1.6"])
|
|
258
|
+
s.add_dependency(%q<bychar>, ["~> 3"])
|
|
259
259
|
s.add_dependency(%q<progressive_io>, ["~> 1.0"])
|
|
260
260
|
s.add_dependency(%q<flame_channel_parser>, ["~> 4.0"])
|
|
261
261
|
s.add_dependency(%q<progressbar>, ["= 0.10.0"])
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tracksperanto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 3
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 3
|
|
8
8
|
- 5
|
|
9
|
-
-
|
|
10
|
-
version: 3.5.
|
|
9
|
+
- 8
|
|
10
|
+
version: 3.5.8
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Julik Tarkhanov
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date:
|
|
18
|
+
date: 2015-06-04 00:00:00 +02:00
|
|
19
19
|
default_executable: tracksperanto
|
|
20
20
|
dependencies:
|
|
21
21
|
- !ruby/object:Gem::Dependency
|
|
@@ -53,12 +53,12 @@ dependencies:
|
|
|
53
53
|
requirements:
|
|
54
54
|
- - ~>
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
|
-
hash:
|
|
56
|
+
hash: 7
|
|
57
57
|
segments:
|
|
58
58
|
- 2
|
|
59
59
|
- 1
|
|
60
|
-
-
|
|
61
|
-
version: 2.1.
|
|
60
|
+
- 6
|
|
61
|
+
version: 2.1.6
|
|
62
62
|
type: :runtime
|
|
63
63
|
version_requirements: *id003
|
|
64
64
|
prerelease: false
|
|
@@ -69,10 +69,10 @@ dependencies:
|
|
|
69
69
|
requirements:
|
|
70
70
|
- - ~>
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
|
-
hash:
|
|
72
|
+
hash: 5
|
|
73
73
|
segments:
|
|
74
|
-
-
|
|
75
|
-
version: "
|
|
74
|
+
- 3
|
|
75
|
+
version: "3"
|
|
76
76
|
type: :runtime
|
|
77
77
|
version_requirements: *id004
|
|
78
78
|
prerelease: false
|