tracksperanto 3.3.6 → 3.3.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,11 @@
1
- == Hacking Tracksperanto
1
+ ## Hacking Tracksperanto
2
2
 
3
- === Tests
3
+ ### Tests
4
4
 
5
5
  Tracksperanto is heavily tested. Please use the Github checkout to also receive some 17+ megabytes of test files that the test suite
6
6
  can chew on. Contributions or patches without tests will be rejected at sight.
7
7
 
8
- === Development environment
8
+ ### Development environment
9
9
 
10
10
  Tracksperanto is currently being developed on Ruby 1.9.3 but it should also work fine on 1.8.7.
11
11
  What you will need is everything mentioned in the Gemfile plus Bundler.
@@ -16,13 +16,13 @@ The test corpus on Tracksperanto is HUGE at the moment, and it makes no sense to
16
16
 
17
17
  So, to get started:
18
18
 
19
- * Make sure you have Ruby and Bundler (+sudo gem install bundler+ if unsure)
19
+ * Make sure you have Ruby and Bundler (`sudo gem install bundler` if unsure)
20
20
  * Checkout the repo at http://github.com/guerilla-di/tracksperanto
21
- * Run +bundle install+ and +bundle exec rake+ to run the tests
21
+ * Run `bundle install` and `bundle exec rake` to run the tests
22
22
  * Do your thing, in a separate branch
23
- * File a pull request or send a patch to +me at julik dot nl+
23
+ * File a pull request or send a patch to **me at julik dot nl**
24
24
 
25
- === Internal tracker representation
25
+ ### Internal tracker representation
26
26
 
27
27
  The trackers are represented by Tracker objects, which work like addressable hashes per frame number. The Tracker objects
28
28
  contain Keyframe objects, and those in turn contain coordinates. The coordinates are stored in absolute pixels, relative to
@@ -31,80 +31,81 @@ the zero coordinate in the lower left corner.
31
31
  Note on subpixel precision: the absolute left/bottom of the image has coordinates 0,0
32
32
  (at the lower left corner of the leftmost bottommost pixel) and 0.5x0.5 in the middle of that pixel.
33
33
 
34
- === Importing your own formats
34
+ ### Importing your own formats
35
35
 
36
36
  To write an import module refer to Tracksperanto::Import::Base
37
37
  docs. Your importer will be configured with width and height of the comp that it is importing, and will get an IO
38
38
  object with the file that you are processing. You should then yield parsed trackers within the each method (tracker objects should
39
39
  be Tracksperanto::Tracker objects or compatibles)
40
40
 
41
- === Exporting your own formats
41
+ ### Exporting your own formats
42
42
 
43
43
  You can easily write an exporter. Refer to the Tracksperanto::Export::Base docs. Note that your exporter should be able to chew alot of data
44
44
  (hundreds of trackers with thousands of keyframes with exported files growing up to 5-10 megs in size are not uncommon!). This means that
45
45
  the exporter should work with streams (smaller parts of the file being exported will be held in memory at a time).
46
46
 
47
- === Ading your own processing steps
47
+ ### Ading your own processing steps
48
48
 
49
49
  You probably want to write a Tool (consult the Tracksperanto::Tool::Base docs) if you need some processing applied to the tracks
50
50
  or their data. A Tool is just like an export module, except that instead it sits between the exporter and the exporting routine. Tools wrap export
51
51
  modules or each other, so you can stack different tool modules together (like "scale first, then move").
52
52
 
53
- === Writing your own processing pipelines from start to finish
53
+ ### Writing your own processing pipelines from start to finish
54
54
 
55
55
  You probably want to write a descendant of Tracksperanto::Pipeline::Base. This is a class that manages a conversion from start to finish, including detecting the
56
56
  input format, allocating output files and building a chain of Tools to process the export. If you want to make a GUI for Tracksperanto you will likely need
57
57
  to write your own Pipeline class or reimplement parts of it.
58
58
 
59
- === Reporting status from long-running operations
59
+ ### Reporting status from long-running operations
60
60
 
61
61
  Almost every module in Tracksperanto has a method called report_progress. This method is used to notify an external callback of what you are doing, and helps keep
62
62
  the software user-friendly. A well-behaved Tracksperanto module should manage it's progress reports properly.
63
63
 
64
- === Sample script
65
-
66
- require "rubygems"
67
- require "tracksperanto"
68
-
69
- include Tracksperanto
70
-
71
- # Create the importer object, for example for a Shake script.
72
- # get_importer will give you the good class even you get the capitalization
73
- # wrong!
74
- some_importer = Tracksperanto.get_importer("shakescript").new
75
-
76
- # This importer needs to know width and height
77
- some_importer.width = 1024
78
- some_importer.height = 576
79
- some_importer.io = File.open("source_file.shk")
80
-
81
- # The importer responds to each() so if your file is not too big you can just load all the trackers
82
- # as an array. If you expect to have alot of trackers investigate a way to buffer them on disk
83
- # instead (see Obuf)
84
- trackers = some_importer.to_a
85
-
86
- # Create the exporter and pass the output file to it
87
- destination_file = File.open("exported_file.other", "wb")
88
- some_exporter = Tracksperanto.get_exporter("flamestabilizer").new(destination_file)
89
-
90
- # Now add some tools, for example a Scale
91
- scaler = Tool::Scaler.new(some_exporter, :x_factor => 2)
92
- # ... and a slip. Tools wrap exporters and other tools, so you can chain them
93
- # ad nauseam
94
- slipper = Tool::Slipper.new(scaler, :offset => 2)
95
-
96
- # Now when we send export commands to the Slipper it will play them through
97
- # to the Scaler and the Scaler in turn will send commands to the exporter.
98
- # As you can see when you run export commands you do not have to use the Tracker
99
- # objects, you just have to stream the right arguments in the right sequence
100
- slipper.start_export(1024, 576)
101
- trackers.each do | t |
102
- slipper.start_tracker_segment(t.name)
103
- t.each do | keyframe |
104
- slipper.export_point(keyframe.frame, keyframe.abs_x, keyframe.abs_y, keyframe.residual)
64
+ ### Sample script
65
+
66
+ require "rubygems"
67
+ require "tracksperanto"
68
+
69
+ include Tracksperanto
70
+
71
+ # Create the importer object, for example for a Shake script.
72
+ # get_importer will give you the good class even you get the capitalization
73
+ # wrong!
74
+ some_importer = Tracksperanto.get_importer("shakescript").new
75
+
76
+ # This importer needs to know width and height
77
+ some_importer.width = 1024
78
+ some_importer.height = 576
79
+ some_importer.io = File.open("source_file.shk")
80
+
81
+ # The importer responds to each() so if your file is not too big you can just load all the trackers
82
+ # as an array. If you expect to have alot of trackers investigate a way to buffer them on disk
83
+ # instead (see Obuf)
84
+ trackers = some_importer.to_a
85
+
86
+ # Create the exporter and pass the output file to it
87
+ destination_file = File.open("exported_file.other", "wb")
88
+ some_exporter = Tracksperanto.get_exporter("flamestabilizer").new(destination_file)
89
+
90
+ # Now add some tools, for example a Scale
91
+ scaler = Tool::Scaler.new(some_exporter, :x_factor => 2)
92
+ # ... and a slip. Tools wrap exporters and other tools, so you can chain them
93
+ # ad nauseam
94
+ slipper = Tool::Slipper.new(scaler, :offset => 2)
95
+
96
+ # Now when we send export commands to the Slipper it will play them through
97
+ # to the Scaler and the Scaler in turn will send commands to the exporter.
98
+ # As you can see when you run export commands you do not have to use the Tracker
99
+ # objects, you just have to stream the right arguments in the right sequence
100
+ slipper.start_export(1024, 576)
101
+ trackers.each do | t |
102
+ slipper.start_tracker_segment(t.name)
103
+ t.each do | keyframe |
104
+ slipper.export_point(keyframe.frame, keyframe.abs_x, keyframe.abs_y, keyframe.residual)
105
+ end
106
+ slipper.end_tracker_segment
105
107
  end
106
- slipper.end_tracker_segment
107
- end
108
- slipper.end_export
109
-
110
- # And we are done!
108
+ slipper.end_export
109
+
110
+ # And we are done!
111
+
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- ruby -*-
2
- source :rubygems
2
+ source 'http://rubygems.org'
3
3
 
4
4
  gem "bundler"
5
5
 
@@ -19,12 +19,11 @@ group :development do
19
19
  gem "linebyline"
20
20
 
21
21
  if RUBY_VERSION > "1.8"
22
- gem "flexmock", "~> 1.3", :require => %w( flexmock flexmock/test_unit )
22
+ gem "flexmock", "~> 1.3.2", :require => %w( flexmock flexmock/test_unit )
23
23
  else
24
24
  gem "flexmock", "~> 0.8", :require => %w( flexmock flexmock/test_unit )
25
25
  end
26
26
 
27
27
  gem "cli_test", "~>1.0"
28
28
  gem "rake-hooks"
29
- gem "ruby-prof"
30
29
  end
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ === 3.3.7
2
+
3
+ * Fix PlanarTracker import support in Nuke 7 scripts
4
+ * Add Nuke CornerPin node support
5
+
1
6
  === 3.3.6
2
7
 
3
8
  * Shake out the latest Bundler integration issues
data/README.rdoc CHANGED
@@ -52,7 +52,7 @@ that you export - and you can apply multiple transformations if desired.
52
52
  == Using Tracksperanto from the command line
53
53
 
54
54
  To run on your own computer, make sure you have Ruby installed. Versions from 1.8.7
55
- and up are supported.
55
+ and up are supported. Wea re also testing on Ruby 2.0.0 now.
56
56
 
57
57
  $ ruby -v
58
58
  ruby 1.9.3p286 (2012-10-12 revision 37165) [x86_64-darwin12.2.0]
@@ -100,7 +100,7 @@ If you want your own copy of the web application at your facility we can discuss
100
100
  * MatchMover REALVIZ Ascii Point Tracks .rz2 file
101
101
  * MatchMover RZML .rzml file
102
102
  * Maya Live track export file
103
- * Nuke .nk script file with Tracker, Reconcile3D and PlanarTracker nodes
103
+ * Nuke .nk script file with Tracker, Reconcile3D, PlanarTracker and CornerPin nodes
104
104
  * PFTrack/PFMatchit .2dt file
105
105
  * Shake .shk script file
106
106
  * Shake .txt tracker file and Nuke CameraTracker auto tracks export
@@ -139,7 +139,7 @@ Consult the --help option to see what is available.
139
139
  == Development
140
140
 
141
141
  If you are interested in reusing Tracksperanto's code or adding modules to the software consult
142
- the {short developer introduction}[https://github.com/guerilla-di/tracksperanto/blob/master/DEVELOPER_DOCS.rdoc]
142
+ the {short developer introduction}[https://github.com/guerilla-di/tracksperanto/blob/master/CONTRIBUTING.md]
143
143
 
144
144
  == Limitations
145
145
 
data/bin/tracksperanto CHANGED
@@ -10,6 +10,9 @@
10
10
  # == Author
11
11
  # Julik <me@julik.nl>
12
12
 
13
+ # Show the message just in case
14
+ $stdout.puts "Starting Tracksperanto. For information and support please contact info#{64.chr}guerilla-di.org"
15
+
13
16
  # Require the xperanto lib, which in turn requires Bundler and pulls in all the gems
14
17
  require File.dirname(__FILE__) + '/../lib/tracksperanto' unless defined?(Tracksperanto)
15
18
  require 'update_hints'
@@ -17,8 +20,7 @@ require 'optparse'
17
20
  require 'progressbar'
18
21
 
19
22
  def disclaimer
20
- "Please consider a small donation to keep Tracksperanto going: http://guerilla-di.org/source-and-license/\n"+
21
- "For information and support please contact info#{64.chr}guerilla-di.org"
23
+ "Please consider a small donation to keep Tracksperanto going: http://guerilla-di.org/source-and-license/"
22
24
  end
23
25
 
24
26
  options = {}
data/lib/import/base.rb CHANGED
@@ -22,7 +22,7 @@ class Tracksperanto::Import::Base
22
22
  # Trakcksperanto will assign the passed width and height to the importer object before running
23
23
  # the import. If not, you can replace the assigned values with your own. At the end of the import
24
24
  # procedure, Tracksperanto will read the values from you again and will use the read values
25
- # for determining the original comp size. +width+ and +height+ MUST return integer values after
25
+ # for determining the original comp size. +width+ and +height+ MUST return unsigned integer values after
26
26
  # the import completes
27
27
  attr_accessor :width, :height
28
28
 
@@ -64,7 +64,7 @@ class Tracksperanto::Import::Base
64
64
  end
65
65
 
66
66
  # The main method of the parser. Should
67
- # yield each tracker that has been fully parsed. After calling this method the caller can ask for
67
+ # yield each Tracker that has been fully parsed. After calling this method the caller can ask for
68
68
  # width and height as well.
69
69
  def each
70
70
  end
@@ -65,28 +65,41 @@ class Tracksperanto::Import::FlameStabilizer < Tracksperanto::Import::Base
65
65
  end
66
66
  end
67
67
 
68
+ # Extracts the animation channels and stores them in Obufs
69
+ # keyed by the channel path (like "tracker1/ref/x")
68
70
  def extract_channels_from_stream(io)
69
71
  parser = StabilizerParser.new
70
72
  parser.logger_proc = method(:report_progress)
71
73
 
72
- channels = Obuf.new
73
- names = []
74
+ channel_map = {}
74
75
  parser.parse(io) do | channel |
75
- channels.push(channel)
76
- names.push(channel.path)
76
+ # Serialize the channel and store it on disk.
77
+ # Flame stabilizers are NOT likely to contain hundreds of
78
+ # trackers unless they were machine-exported from something,
79
+ # but we need to be memory-aware when we do things like this.
80
+ # On our test suite we lose half a second on disk IO overhead
81
+ # of the Obuf here, which is an acceptable compromise.
82
+ # To get rid of the disk-based cache just toss the outer
83
+ # Obuf constructor and pass in an Array
84
+ channel_map[channel.path] = Obuf.new([channel])
77
85
  end
78
86
 
79
- [channels, names]
87
+ channel_map
80
88
  end
81
89
 
82
- def scavenge_trackers_from_channels(channels, names)
83
- channels.each do |c|
84
- next unless c.name =~ /\/ref\/x/
90
+ def scavenge_trackers_from_channels(channel_map, names)
91
+ # Use Hash#keys.sort because we want a consistent export order
92
+ # irregardless of the Ruby version in use
93
+ # (hash keys are ordered on 1.9 and not ordered on 1.8)
94
+ channel_map.keys.sort.each do |c|
95
+ next unless c =~ /\/ref\/x$/
85
96
 
86
- report_progress("Detected reference channel #{c.name}")
97
+ report_progress("Detected reference channel #{c.inspect}")
87
98
 
88
- t = grab_tracker(channels, c, names)
89
- yield(t) if t
99
+ extracted_tracker = grab_tracker(channel_map, c)
100
+ if extracted_tracker
101
+ yield(extracted_tracker)
102
+ end
90
103
  end
91
104
  end
92
105
 
@@ -94,29 +107,25 @@ class Tracksperanto::Import::FlameStabilizer < Tracksperanto::Import::Base
94
107
  chan.map{|key| [key.frame, key.value]}
95
108
  end
96
109
 
97
- def grab_tracker(channels, track_x, names)
98
- t = Tracksperanto::Tracker.new(:name => track_x.name.split('/').shift)
110
+ def grab_tracker(channel_map, ref_x_channel_name)
111
+ t = Tracksperanto::Tracker.new(:name => ref_x_channel_name.split('/').shift)
99
112
 
100
113
  report_progress("Extracting tracker #{t.name}")
101
114
 
102
- # This takes a LONG time when we have alot of channels, we need a precache of
103
- # some sort to do this
104
- ref_idx = names.index("#{t.name}/ref/y")
105
- shift_x_idx = names.index("#{t.name}/shift/x")
106
- shift_y_idx = names.index("#{t.name}/shift/y")
107
-
108
- track_y = channels[ref_idx]
109
- shift_x = channels[shift_x_idx]
110
- shift_y = channels[shift_y_idx]
115
+ shift_x = channel_map["#{t.name}/shift/x"][0]
116
+ shift_y = channel_map["#{t.name}/shift/y"][0]
117
+ ref_x = channel_map["#{t.name}/ref/x"][0]
118
+ ref_y = channel_map["#{t.name}/ref/y"][0]
111
119
 
120
+ # Collapse separate X and Y curves into series of XY values
112
121
  shift_tuples = zip_curve_tuples(channel_to_frames_and_values(shift_x), channel_to_frames_and_values(shift_y))
113
- track_tuples = zip_curve_tuples(channel_to_frames_and_values(track_x), channel_to_frames_and_values(track_y))
122
+ ref_tuples = zip_curve_tuples(channel_to_frames_and_values(ref_x), channel_to_frames_and_values(ref_y))
114
123
 
115
124
  # If the channels are just empty go to next tracker
116
- return if shift_tuples.empty? || track_tuples.empty?
125
+ return if shift_tuples.empty? || ref_tuples.empty?
117
126
 
118
127
  report_progress("Detecting base value")
119
- base_x, base_y = find_base_x_and_y(track_tuples, shift_tuples)
128
+ base_x, base_y = find_base_x_and_y(ref_tuples, shift_tuples)
120
129
 
121
130
  total_kf = 1
122
131
  t.keyframes = shift_tuples.map do | (at, x, y) |
@@ -131,10 +140,10 @@ class Tracksperanto::Import::FlameStabilizer < Tracksperanto::Import::Base
131
140
  return t
132
141
  end
133
142
 
134
- def find_base_x_and_y(track_tuples, shift_tuples)
135
- base_track_tuple = track_tuples.find do | track_tuple |
143
+ def find_base_x_and_y(ref_tuples, shift_tuples)
144
+ base_ref_tuple = ref_tuples.find do | track_tuple |
136
145
  shift_tuples.find { |shift_tuple| shift_tuple[0] == track_tuple[0] }
137
146
  end
138
- (base_track_tuple || track_tuples[0])[1..2]
147
+ (base_ref_tuple || ref_tuples[0])[1..2]
139
148
  end
140
149
  end
@@ -5,7 +5,7 @@ require 'tickly'
5
5
  class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
6
6
 
7
7
  def self.human_name
8
- "Nuke .nk script file with Tracker, Reconcile3D and PlanarTracker nodes"
8
+ "Nuke .nk script file with Tracker, Reconcile3D, PlanarTracker and CornerPin nodes"
9
9
  end
10
10
 
11
11
  def self.distinct_file_ext
@@ -13,7 +13,8 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
13
13
  end
14
14
 
15
15
  def self.known_snags
16
- 'The only supported nodes that we can extract tracks from are Reconcile3D, PlanarTracker and Tracker (supported Nuke versions are 5, 6 and 7)'
16
+ 'The only supported nodes that we can extract tracks from are Reconcile3D,'
17
+ + ' PlanarTracker and Tracker (supported Nuke versions are 5, 6 and 7)'
17
18
  end
18
19
 
19
20
  def each
@@ -21,7 +22,9 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
21
22
  parser.add_node_handler_class(Tracker3)
22
23
  parser.add_node_handler_class(Reconcile3D)
23
24
  parser.add_node_handler_class(PlanarTracker1_0)
25
+ parser.add_node_handler_class(PlanarTracker)
24
26
  parser.add_node_handler_class(Tracker4)
27
+ parser.add_node_handler_class(CornerPin2D)
25
28
 
26
29
  parser.parse(@io) do | node |
27
30
  node.trackers.each do | t |
@@ -87,12 +90,26 @@ class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
87
90
  end
88
91
  end
89
92
 
93
+ # Planar tracker in Nuke 6
90
94
  class PlanarTracker1_0 < Tracker3
91
95
  def point_channels
92
96
  %w( outputBottomLeft outputBottomRight outputTopLeft outputTopRight)
93
97
  end
94
98
  end
95
99
 
100
+ # Planar tracker in Nuke 7
101
+ class PlanarTracker < PlanarTracker1_0
102
+ def point_channels
103
+ %w( outputBottomLeft outputBottomRight outputTopLeft outputTopRight)
104
+ end
105
+ end
106
+
107
+ class CornerPin2D < Tracker3
108
+ def point_channels
109
+ %w( to1 to2 to3 to4 )
110
+ end
111
+ end
112
+
96
113
  class Tracker4 < Tracker3
97
114
 
98
115
  def initialize(options)
@@ -76,7 +76,9 @@ class Tracksperanto::Import::PFTrack < Tracksperanto::Import::Base
76
76
  (1..num_of_keyframes).map do | keyframe_idx |
77
77
  report_progress("Reading keyframe #{keyframe_idx} of #{num_of_keyframes} in #{t.name}")
78
78
  f, x, y, residual = io.gets.chomp.split
79
- t.keyframe!(:frame => f.to_f - 1, :abs_x => from_pfcoord(x), :abs_y => from_pfcoord(y), :residual => residual.to_f * 8)
79
+ t.keyframe!(:frame => f.to_f - 1,
80
+ :abs_x => from_pfcoord(x), :abs_y => from_pfcoord(y),
81
+ :residual => residual.to_f * 8)
80
82
  end
81
83
  end
82
84
 
@@ -13,7 +13,8 @@ class Tracksperanto::Import::ShakeScript < Tracksperanto::Import::Base
13
13
  end
14
14
 
15
15
  def self.known_snags
16
- 'Expressions in node parameters may cause parse errors or incomplete imports. Take care to remove expressions or nodes containing them first.'
16
+ 'Expressions in node parameters may cause parse errors or incomplete imports. ' +
17
+ 'Take care to remove expressions or nodes containing them first.'
17
18
  end
18
19
 
19
20
  def each
data/lib/tracksperanto.rb CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  module Tracksperanto
5
5
  PATH = File.expand_path(File.dirname(__FILE__))
6
- VERSION = '3.3.6'
6
+ VERSION = '3.3.7'
7
7
 
8
8
  module Import; end
9
9
  module Export; end
@@ -2,7 +2,8 @@
2
2
  # Implements the conventional constructor with "hash of attributes" and block support
3
3
  module Tracksperanto::BlockInit
4
4
  def initialize(object_attribute_hash = {})
5
- object_attribute_hash.map { |(k, v)| send("#{k}=", v) }
5
+ m = method(respond_to?(:public_send) ? :public_send : :send)
6
+ object_attribute_hash.map { |(k, v)| m.call("#{k}=", v) }
6
7
  yield(self) if block_given?
7
8
  end
8
9
  end
@@ -9,16 +9,16 @@
9
9
  class Tracksperanto::Keyframe
10
10
  include Tracksperanto::Casts, Tracksperanto::BlockInit, Comparable
11
11
 
12
- # Absolute integer frame where this keyframe is placed, 0 based
12
+ # Integer frame where this keyframe is placed, 0-based
13
13
  attr_accessor :frame
14
14
 
15
- # Absolute float X value of the point, zero is lower left
15
+ # Float X value of the point, zero is lower left
16
16
  attr_accessor :abs_x
17
17
 
18
- # Absolute float Y value of the point, zero is lower left
18
+ # Float Y value of the point, zero is lower left
19
19
  attr_accessor :abs_y
20
20
 
21
- # Absolute float residual (0 is "spot on")
21
+ # Float residual (0 is "spot on")
22
22
  attr_accessor :residual
23
23
 
24
24
  cast_to_float :abs_x, :abs_y, :residual
@@ -7,7 +7,7 @@ class BoujouExportTest < Test::Unit::TestCase
7
7
 
8
8
  def test_export_output_written
9
9
  t = Time.local(2010, "Apr", 15, 17, 21, 26)
10
- flexmock(Time).should_receive(:now).once.and_return(t)
10
+ flexmock(Time).should_receive(:now).and_return(t)
11
11
  ensure_same_output Tracksperanto::Export::Boujou, P
12
12
  end
13
13
 
@@ -1,13 +1,13 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require File.expand_path(File.dirname(__FILE__)) + '/../helper'
3
3
 
4
- class FlameStabilizerExportTestTest < Test::Unit::TestCase
4
+ class TestFlameStabilizerExport < Test::Unit::TestCase
5
5
  include ParabolicTracks
6
6
  P = File.dirname(__FILE__) + "/samples/ref_flame.stabilizer"
7
7
 
8
8
  def test_export_output_written
9
9
  t = Time.local(2010, "Feb", 18, 17, 22, 12)
10
- flexmock(Time).should_receive(:now).once.and_return(t)
10
+ flexmock(Time).should_receive(:now).and_return(t)
11
11
  ensure_same_output Tracksperanto::Export::FlameStabilizer, P
12
12
  end
13
13
 
@@ -0,0 +1,10 @@
1
+ Tracksperanto has a huge test corpus of test files, which is stored in the project's Github repo.
2
+
3
+ This is why the repo is so big.
4
+
5
+ However, most users of Tracksperanto are actually _users_, they won't need
6
+ all the testing data. And without this data, tracksperanto is less than
7
+ 100 kilobytes in size.
8
+
9
+ If you intend to actually write code that uses Tracksperanto or to fix
10
+ a bug, you will most definitely need all the test data. In that case, just do a git checkout.
@@ -1,7 +1,7 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require File.expand_path(File.dirname(__FILE__)) + '/../helper'
3
3
 
4
- class FlameImportTest < Test::Unit::TestCase
4
+ class TestFlameImport < Test::Unit::TestCase
5
5
  DELTA = 0.1
6
6
 
7
7
  def test_parsing_from_flame
@@ -105,8 +105,8 @@ class FlameImportTest < Test::Unit::TestCase
105
105
  def test_bilinear_passes_proper_naming
106
106
  fixture = File.open(File.dirname(__FILE__) + '/samples/flame_stabilizer/cornerpin_2012.stabilizer')
107
107
  trackers = Tracksperanto::Import::FlameStabilizer.new(:io => fixture).to_a
108
- assert_equal "top_left", trackers[0].name
109
- assert_equal "bottom_right", trackers[-1].name
108
+ tracker_order = ["bottom_left", "bottom_right", "top_left", "top_right"]
109
+ assert_equal tracker_order, trackers.map(&:name)
110
110
  end
111
111
 
112
112
  end
@@ -6,6 +6,7 @@ class MatchMoverImportTest < Test::Unit::TestCase
6
6
 
7
7
  P = File.dirname(__FILE__) + '/samples/match_mover/kipPointsMatchmover.rz2'
8
8
  P2 = File.dirname(__FILE__) + '/samples/match_mover/NonSequentialMatchmoverPoints.rz2'
9
+ P3 = File.dirname(__FILE__) + '/samples/match_mover/cha_171_1020_atb_v001.rz2'
9
10
 
10
11
  def test_introspects_properly
11
12
  i = Tracksperanto::Import::MatchMover
@@ -22,6 +23,14 @@ class MatchMoverImportTest < Test::Unit::TestCase
22
23
  assert_equal 0, trackers[0][0].frame, "Should have offset the first frame to 0"
23
24
  end
24
25
 
26
+ def test_parsing_case_nil_exception
27
+ fixture = File.open(P3)
28
+
29
+ parser = Tracksperanto::Import::MatchMover.new(:io => fixture)
30
+ trackers = parser.to_a
31
+ assert_equal 6, trackers.length
32
+ end
33
+
25
34
  def test_parsing_from_matchmover
26
35
  fixture = File.open(P)
27
36
 
@@ -6,7 +6,7 @@ class NukeImportTest < Test::Unit::TestCase
6
6
 
7
7
  def test_introspects_properly
8
8
  i = Tracksperanto::Import::NukeScript
9
- assert_equal "Nuke .nk script file with Tracker, Reconcile3D and PlanarTracker nodes", i.human_name
9
+ assert_equal "Nuke .nk script file with Tracker, Reconcile3D, PlanarTracker and CornerPin nodes", i.human_name
10
10
  assert !i.autodetects_size?
11
11
  end
12
12
 
@@ -34,6 +34,17 @@ class NukeImportTest < Test::Unit::TestCase
34
34
  assert_equal 128, trackers[0].length
35
35
  end
36
36
 
37
+ def test_parsing_cornerpin
38
+ fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/cornerpin.nk')
39
+
40
+ parser = Tracksperanto::Import::NukeScript.new(:io => fixture)
41
+ parser.width = 4096
42
+ parser.height = 2304
43
+
44
+ trackers = parser.to_a
45
+ assert_equal 4, trackers.length
46
+ end
47
+
37
48
  def test_parsing_planar_tracker
38
49
  fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/planar.nk')
39
50
 
@@ -49,6 +60,21 @@ class NukeImportTest < Test::Unit::TestCase
49
60
  assert_equal ref_names, trackers.map{|e| e.name }
50
61
  end
51
62
 
63
+ def test_parsing_planar_tracker_nuke7
64
+ fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/nuke7_planar.nk')
65
+
66
+ parser = Tracksperanto::Import::NukeScript.new(:io => fixture)
67
+ parser.width = 1920
68
+ parser.height = 1080
69
+
70
+ trackers = parser.to_a
71
+ assert_equal 4, trackers.length
72
+
73
+ ref_names = %w( PlanarTracker1_outputBottomLeft PlanarTracker1_outputBottomRight
74
+ PlanarTracker1_outputTopLeft PlanarTracker1_outputTopRight )
75
+ assert_equal ref_names, trackers.map{|e| e.name }
76
+ end
77
+
52
78
  def test_parsing_from_nuke
53
79
  fixture = File.open(File.dirname(__FILE__) + '/samples/nuke/one_tracker_with_break.nk')
54
80
 
@@ -0,0 +1,49 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__)) + '/helper'
3
+
4
+ class TestBlockInit < Test::Unit::TestCase
5
+
6
+ class Settable
7
+ include Tracksperanto::BlockInit
8
+
9
+ attr_accessor :foo, :bar
10
+
11
+ private
12
+ def privatized=(something)
13
+ end
14
+ end
15
+
16
+ def test_block_init_with_hash
17
+ s = Settable.new(:foo => "x", :bar => "y")
18
+ assert_equal "x", s.foo
19
+ assert_equal "y", s.bar
20
+ end
21
+
22
+ def test_block_init_with_hash_raises_on_unknown_attribute
23
+ assert_raise(NoMethodError) { Settable.new(:nonexistent => true) }
24
+ end
25
+
26
+ def test_block_init_with_block_yields_the_object
27
+ within_blk = nil
28
+ s = Settable.new do | f |
29
+ within_blk = f
30
+ f.foo = "x"
31
+ end
32
+
33
+ assert_equal s, within_blk, "Should have yielded the object to the blk"
34
+ assert_equal "x", s.foo
35
+ end
36
+
37
+ def test_block_init_attributes_overwrite_hash_attributes
38
+ s = Settable.new(:foo => "bar") { |f| f.foo = "x" }
39
+ assert_equal "x", s.foo
40
+ end
41
+
42
+ if RUBY_VERSION > '1.9'
43
+ def test_block_init_uses_public_send
44
+ assert_raise(NoMethodError) { Settable.new(:privatized => true) }
45
+ end
46
+ end
47
+
48
+
49
+ end
@@ -5,20 +5,19 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "tracksperanto"
8
- s.version = "3.3.6"
8
+ s.version = "3.3.7"
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 = "2013-04-04"
12
+ s.date = "2013-07-25"
13
13
  s.description = "Converts 2D track exports between different apps like Flame, MatchMover, PFTrack..."
14
14
  s.email = "me@julik.nl"
15
15
  s.executables = ["tracksperanto"]
16
16
  s.extra_rdoc_files = [
17
- "DEVELOPER_DOCS.rdoc",
18
17
  "README.rdoc"
19
18
  ]
20
19
  s.files = [
21
- "DEVELOPER_DOCS.rdoc",
20
+ "CONTRIBUTING.md",
22
21
  "Gemfile",
23
22
  "History.txt",
24
23
  "MIT_LICENSE.txt",
@@ -141,7 +140,7 @@ Gem::Specification.new do |s|
141
140
  "test/export/test_syntheyes_export.rb",
142
141
  "test/export/test_xsi_python_export.rb",
143
142
  "test/helper.rb",
144
- "test/import/README_SAMPLES.txt",
143
+ "test/import/README.rdoc",
145
144
  "test/import/test_3de_import.rb",
146
145
  "test/import/test_3de_import3.rb",
147
146
  "test/import/test_boujou_import.rb",
@@ -165,6 +164,7 @@ Gem::Specification.new do |s|
165
164
  "test/subpixel/subpixel_grid.sni",
166
165
  "test/subpixel/subpixel_grid.tif",
167
166
  "test/subpixel/sy_subpix_2dpaths.txt",
167
+ "test/test_block_init.rb",
168
168
  "test/test_buffer_io.rb",
169
169
  "test/test_casts.rb",
170
170
  "test/test_cli.rb",
@@ -202,7 +202,7 @@ Gem::Specification.new do |s|
202
202
  s.homepage = "http://guerilla-di.org/tracksperanto"
203
203
  s.licenses = ["MIT"]
204
204
  s.require_paths = ["lib"]
205
- s.rubygems_version = "1.8.24"
205
+ s.rubygems_version = "1.8.25"
206
206
  s.summary = "A universal 2D tracks converter"
207
207
 
208
208
  if s.respond_to? :specification_version then
@@ -221,10 +221,9 @@ Gem::Specification.new do |s|
221
221
  s.add_development_dependency(%q<jeweler>, [">= 0"])
222
222
  s.add_development_dependency(%q<rake>, [">= 0"])
223
223
  s.add_development_dependency(%q<linebyline>, [">= 0"])
224
- s.add_development_dependency(%q<flexmock>, ["~> 1.3"])
224
+ s.add_development_dependency(%q<flexmock>, ["~> 1.3.2"])
225
225
  s.add_development_dependency(%q<cli_test>, ["~> 1.0"])
226
226
  s.add_development_dependency(%q<rake-hooks>, [">= 0"])
227
- s.add_development_dependency(%q<ruby-prof>, [">= 0"])
228
227
  else
229
228
  s.add_dependency(%q<bundler>, [">= 0"])
230
229
  s.add_dependency(%q<obuf>, ["~> 1.1"])
@@ -238,10 +237,9 @@ Gem::Specification.new do |s|
238
237
  s.add_dependency(%q<jeweler>, [">= 0"])
239
238
  s.add_dependency(%q<rake>, [">= 0"])
240
239
  s.add_dependency(%q<linebyline>, [">= 0"])
241
- s.add_dependency(%q<flexmock>, ["~> 1.3"])
240
+ s.add_dependency(%q<flexmock>, ["~> 1.3.2"])
242
241
  s.add_dependency(%q<cli_test>, ["~> 1.0"])
243
242
  s.add_dependency(%q<rake-hooks>, [">= 0"])
244
- s.add_dependency(%q<ruby-prof>, [">= 0"])
245
243
  end
246
244
  else
247
245
  s.add_dependency(%q<bundler>, [">= 0"])
@@ -256,10 +254,9 @@ Gem::Specification.new do |s|
256
254
  s.add_dependency(%q<jeweler>, [">= 0"])
257
255
  s.add_dependency(%q<rake>, [">= 0"])
258
256
  s.add_dependency(%q<linebyline>, [">= 0"])
259
- s.add_dependency(%q<flexmock>, ["~> 1.3"])
257
+ s.add_dependency(%q<flexmock>, ["~> 1.3.2"])
260
258
  s.add_dependency(%q<cli_test>, ["~> 1.0"])
261
259
  s.add_dependency(%q<rake-hooks>, [">= 0"])
262
- s.add_dependency(%q<ruby-prof>, [">= 0"])
263
260
  end
264
261
  end
265
262
 
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: 3.3.6
4
+ version: 3.3.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-04 00:00:00.000000000 Z
12
+ date: 2013-07-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -210,7 +210,7 @@ dependencies:
210
210
  requirements:
211
211
  - - ~>
212
212
  - !ruby/object:Gem::Version
213
- version: '1.3'
213
+ version: 1.3.2
214
214
  type: :development
215
215
  prerelease: false
216
216
  version_requirements: !ruby/object:Gem::Requirement
@@ -218,7 +218,7 @@ dependencies:
218
218
  requirements:
219
219
  - - ~>
220
220
  - !ruby/object:Gem::Version
221
- version: '1.3'
221
+ version: 1.3.2
222
222
  - !ruby/object:Gem::Dependency
223
223
  name: cli_test
224
224
  requirement: !ruby/object:Gem::Requirement
@@ -251,22 +251,6 @@ dependencies:
251
251
  - - ! '>='
252
252
  - !ruby/object:Gem::Version
253
253
  version: '0'
254
- - !ruby/object:Gem::Dependency
255
- name: ruby-prof
256
- requirement: !ruby/object:Gem::Requirement
257
- none: false
258
- requirements:
259
- - - ! '>='
260
- - !ruby/object:Gem::Version
261
- version: '0'
262
- type: :development
263
- prerelease: false
264
- version_requirements: !ruby/object:Gem::Requirement
265
- none: false
266
- requirements:
267
- - - ! '>='
268
- - !ruby/object:Gem::Version
269
- version: '0'
270
254
  description: Converts 2D track exports between different apps like Flame, MatchMover,
271
255
  PFTrack...
272
256
  email: me@julik.nl
@@ -274,10 +258,9 @@ executables:
274
258
  - tracksperanto
275
259
  extensions: []
276
260
  extra_rdoc_files:
277
- - DEVELOPER_DOCS.rdoc
278
261
  - README.rdoc
279
262
  files:
280
- - DEVELOPER_DOCS.rdoc
263
+ - CONTRIBUTING.md
281
264
  - Gemfile
282
265
  - History.txt
283
266
  - MIT_LICENSE.txt
@@ -400,7 +383,7 @@ files:
400
383
  - test/export/test_syntheyes_export.rb
401
384
  - test/export/test_xsi_python_export.rb
402
385
  - test/helper.rb
403
- - test/import/README_SAMPLES.txt
386
+ - test/import/README.rdoc
404
387
  - test/import/test_3de_import.rb
405
388
  - test/import/test_3de_import3.rb
406
389
  - test/import/test_boujou_import.rb
@@ -424,6 +407,7 @@ files:
424
407
  - test/subpixel/subpixel_grid.sni
425
408
  - test/subpixel/subpixel_grid.tif
426
409
  - test/subpixel/sy_subpix_2dpaths.txt
410
+ - test/test_block_init.rb
427
411
  - test/test_buffer_io.rb
428
412
  - test/test_casts.rb
429
413
  - test/test_cli.rb
@@ -472,7 +456,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
472
456
  version: '0'
473
457
  segments:
474
458
  - 0
475
- hash: -4545677537433489103
459
+ hash: -4537325556160571006
476
460
  required_rubygems_version: !ruby/object:Gem::Requirement
477
461
  none: false
478
462
  requirements:
@@ -481,7 +465,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
481
465
  version: '0'
482
466
  requirements: []
483
467
  rubyforge_project:
484
- rubygems_version: 1.8.24
468
+ rubygems_version: 1.8.25
485
469
  signing_key:
486
470
  specification_version: 3
487
471
  summary: A universal 2D tracks converter
@@ -1,5 +0,0 @@
1
- Tracksperanto has a huge test corpus of test files, which is stored in the project's Github repo.
2
- Checkout the repo to run tests against these samples.
3
- Since most users of Tracksperanto are actually USERS, they do not need to download the 4 megabytes of test fixtures
4
- as opposed to 80 kilobytes of the program itself. If you want to develop against Tracksperanto we advise you DO use
5
- the test corpus though, so please pretty please just pull it off Github.