tracksperanto 2.10.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 2.11.0
2
+
3
+ * This release adds a Softimage|XSI export module which outputs a Python script with moving nulls on an image plane
4
+
1
5
  === 2.10.0
2
6
 
3
7
  * Nuke importer now supports PlanarTracker nodes and their corner-pin output
data/README.rdoc CHANGED
@@ -73,6 +73,7 @@ Export only:
73
73
  * AfterEffects .jsx script that creates one null object per tracker (run through the script editor)
74
74
  * Ruby (will make calls to Tracksperanto to create trackers/keyframes) - useful if you want to play with trackers as data
75
75
  * Maya locators (animated locators on an image plane)
76
+ * Softimage/XSI Python script (animated nulls on an image plane)
76
77
 
77
78
  == Editing your tracks while converting
78
79
 
data/lib/export/xsi.rb ADDED
@@ -0,0 +1,69 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # Export each tracker as a moving Softimage|XSI null
3
+ class Tracksperanto::Export::XSI < Tracksperanto::Export::Base
4
+
5
+ IMAGE_PLANE = 'Application.CreatePrim("Grid", "MeshSurface", "", "")
6
+ Application.SetValue("grid.Name", "ImagePlane", "")
7
+ Application.SetValue("ImagePlane.grid.ulength", %0.5f, "")
8
+ Application.SetValue("ImagePlane.grid.vlength", %0.5f, "")
9
+ Application.Rotate("", 90, 0, 0, "siRelative", "siLocal", "siObj", "siXYZ", "", "", "", "", "", "", "", 0, "")'
10
+
11
+ MULTIPLIER = 10.0
12
+
13
+ def self.desc_and_extension
14
+ "xsi_nulls.py"
15
+ end
16
+
17
+ def self.human_name
18
+ "Autodesk Softimage nulls Python script"
19
+ end
20
+
21
+ def start_export(w, h)
22
+ # Pixel sizes are HUGE. Hence we downscale
23
+ @factor = (1 / w.to_f) * MULTIPLIER
24
+ @true_width, @true_height = w * @factor, h * @factor
25
+
26
+ # Generate a Grid primitive
27
+ @io.puts(IMAGE_PLANE % [@true_width, @true_height])
28
+ @tracker_names = []
29
+ end
30
+
31
+ def start_tracker_segment(tracker_name)
32
+ @t = tracker_name
33
+ @io.puts("# Data for tracker %s" % @t)
34
+ @io.puts 'Application.GetPrim("Null", "", "", "")'
35
+ @io.puts('Application.SetValue("null.Name", "%s", "")' % @t)
36
+ # Application.ToggleSelection("Track_Point_02", "", "")
37
+ # Select the tracker that we will animate
38
+ @io.puts('Application.SelectObj("%s", "", True)' % @t)
39
+ end
40
+
41
+ def end_tracker_segment
42
+ # Parent the null to the image plane
43
+ @tracker_names.push(@t)
44
+ end
45
+
46
+ def export_point(frame, abs_float_x, abs_float_y, float_residual)
47
+ coords = get_coordinates(abs_float_x, abs_float_y)
48
+ @io.puts('Application.Translate("", %0.5f, %0.5f, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")'% coords)
49
+ @io.puts('Application.SaveKeyOnKeyable("%s", %d, "", "", "", False, "")' % [@t, frame + 1])
50
+ end
51
+
52
+ def end_export
53
+ # Create a Model group and parent all the trackers and the image plane to it
54
+ @io.puts('Application.DeselectAll()')
55
+ @io.puts('Application.AddToSelection("ImagePlane", "", "")')
56
+ @tracker_names.each do | tracker_name |
57
+ @io.puts('Application.AddToSelection("%s", "", "")' % tracker_name)
58
+ end
59
+ @io.puts('Application.CreateModel("", "", "", "")')
60
+ @io.puts('Application.SetValue("Model.Name", "Tracksperanto", "")')
61
+ end
62
+
63
+ private
64
+
65
+ def get_coordinates(x, y)
66
+ # Get the coords multiplied by factor, and let the scene origin be the center of the composition
67
+ [(x * @factor) - (@true_width / 2), y * @factor - (@true_height / 2)]
68
+ end
69
+ end
data/lib/import/base.rb CHANGED
@@ -38,9 +38,8 @@ class Tracksperanto::Import::Base
38
38
  end
39
39
 
40
40
  # Return an extension WITH DOT if this format has a typical extension that
41
- # you can detect (like ".nk" for Nuke)
41
+ # you can detect (like ".nk" for Nuke)
42
42
  def self.distinct_file_ext
43
- nil
44
43
  end
45
44
 
46
45
  # Should return a human-readable (read: properly capitalized and with spaces) name of the
@@ -49,6 +48,10 @@ class Tracksperanto::Import::Base
49
48
  "Abstract import format"
50
49
  end
51
50
 
51
+ # Returns a textual description of things to check when the user wants to import from this specific format
52
+ def self.known_snags
53
+ end
54
+
52
55
  # Return true from this method if your importer can deduce the comp size from the passed file
53
56
  def self.autodetects_size?
54
57
  false
@@ -14,6 +14,10 @@ class Tracksperanto::Import::MayaLive < Tracksperanto::Import::Base
14
14
  true
15
15
  end
16
16
 
17
+ def self.known_snags
18
+ 'Only square pixel aspect ratio shots are supported.'
19
+ end
20
+
17
21
  COMMENT = /^# /
18
22
 
19
23
  def each
@@ -5,7 +5,7 @@ require File.expand_path(File.dirname(__FILE__)) + "/nuke_grammar/utils"
5
5
  class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base
6
6
 
7
7
  def self.human_name
8
- "Nuke .nk script file with Tracker or Reconcile3D nodes"
8
+ "Nuke .nk script file with Tracker, Reconcile3D and PlanarTracker nodes"
9
9
  end
10
10
 
11
11
  def self.distinct_file_ext
@@ -9,6 +9,11 @@ class Tracksperanto::Import::PFTrack < Tracksperanto::Import::Base
9
9
  ".2dt"
10
10
  end
11
11
 
12
+ def self.known_snags
13
+ 'PFTrack only exports the trackers for the solved part of the shot. To export the whole shot, ' +
14
+ "first delete the camera solve."
15
+ end
16
+
12
17
  CHARACTERS_OR_QUOTES = /[AZaz"]/
13
18
  INTS = /^\d+$/
14
19
 
@@ -12,6 +12,10 @@ class Tracksperanto::Import::ShakeScript < Tracksperanto::Import::Base
12
12
  ".shk"
13
13
  end
14
14
 
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.'
17
+ end
18
+
15
19
  def each
16
20
  s = Sentinel.new
17
21
  s.progress_proc = method(:report_progress)
data/lib/pipeline/base.rb CHANGED
@@ -14,10 +14,18 @@ module Tracksperanto::Pipeline
14
14
  end
15
15
 
16
16
  class NoTrackersRecoveredError < RuntimeError
17
+ def initialize(importer)
18
+ if importer.class.known_snags
19
+ @snags = "Also note that this particular format (%s) has the following snags: %s" % [importer.const_name, importer.snags]
20
+ end
21
+ end
22
+
17
23
  def message;
18
- "Could not recover any non-empty trackers from this file.\n" +
19
- "Wrong import format maybe?\n" +
20
- "Note that PFTrack will only export trackers from the solved segment of the shot.";
24
+ [
25
+ "Could not recover any non-empty trackers from this file.",
26
+ "Wrong import format maybe?",
27
+ @snags
28
+ ].join("\n")
21
29
  end
22
30
  end
23
31
 
@@ -165,7 +173,7 @@ module Tracksperanto::Pipeline
165
173
  obuf = Obuf.new(Tracksperanto::YieldNonEmpty.new(importer))
166
174
 
167
175
  report_progress(percent_complete = 50.0, "Validating #{obuf.size} imported trackers")
168
- raise NoTrackersRecoveredError if obuf.size.zero?
176
+ raise NoTrackersRecoveredError.new(importer) if obuf.size.zero?
169
177
 
170
178
  report_progress(percent_complete, "Starting export")
171
179
 
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 = '2.10.0'
6
+ VERSION = '2.11.0'
7
7
 
8
8
  module Import; end
9
9
  module Export; end
@@ -1,6 +1,6 @@
1
1
  Export tests are conformance tests. That means that:
2
2
 
3
- 1) An export is made using Tracksperanto
3
+ 1) An export is made using Tracksperanto
4
4
  2) This export gets checked by importing it into the main app
5
5
  that accepts such files
6
6
  3) The export is compared with Tracksperanto output in the test
@@ -9,9 +9,16 @@ This means that unless you own an app that accepts this particular format
9
9
  you cannot overwrite the export with your own since you got no way to verify
10
10
  that the export works
11
11
 
12
- The current test set consists of the two parabolic curves that cross. The second
13
- parabolic curve goes left, the first one - right, and they start at opposite
14
- corners of the reference 1920x1080 export. At the first point the track has the residual of 0,
15
- at the end of the curve - the biggest residual (PFTrack marks it red exactly at the last keyframe).
12
+ The current test set consists of three trackers. First - two two parabolic curves that cross.
13
+ The first tracker goes left to right, the second right to left and they start at opposite
14
+ corners of the reference 1920x1080 export.
16
15
 
17
- In the middle of the curves a couple of keyframes is skipped to verify that proper gaps are written into the export.
16
+ At the first point the track has the residual of 0, at the end of the curve - the biggest
17
+ residual (PFTrack marks it red exactly at the last keyframe).
18
+
19
+ The third tracker has one keyframe and is positioned exactly in the middle.
20
+
21
+ In the middle of the curves a couple of keyframes is skipped to verify that proper gaps are written into the export.
22
+
23
+ When changing the export parameters you will need to overwrite all test exports, to do so set the environment variable
24
+ called TRACKSPERANTO_OVERWRITE_ALL_TEST_DATA
@@ -57,7 +57,7 @@ pos.setValueAtTime(convertFrameToSeconds(layer1, 19), [96.00000,874.80000]);
57
57
  pos.setValueAtTime(convertFrameToSeconds(layer1, 20), [0.00000,1080.00000]);
58
58
 
59
59
  var layer2 = app.project.activeItem.layers.addNull();
60
- layer2.name = "SingleFrame";
60
+ layer2.name = "SingleFrame_InTheMiddle";
61
61
 
62
62
  var pos = layer2.property("Transform").property("Position");
63
63
  pos.setValueAtTime(convertFrameToSeconds(layer2, 0), [970.00000,530.00000]);
@@ -83,8 +83,8 @@ setKeyframe -time 20 -value 0.50000 "Parabolic_2_from_bottom_right.tx";
83
83
  setKeyframe -time 20 -value 1.06875 "Parabolic_2_from_bottom_right.ty";
84
84
  setKeyframe -time 21 -value 0.00000 "Parabolic_2_from_bottom_right.tx";
85
85
  setKeyframe -time 21 -value 0.00000 "Parabolic_2_from_bottom_right.ty";
86
- spaceLocator -name "SingleFrame" -p 0 0 0;
87
- setKeyframe -time 1 -value 5.05208 "SingleFrame.tx";
88
- setKeyframe -time 1 -value 2.86458 "SingleFrame.ty";
89
- select -r TracksperantoImagePlane Parabolic_1_from_top_left Parabolic_2_from_bottom_right SingleFrame;
86
+ spaceLocator -name "SingleFrame_InTheMiddle" -p 0 0 0;
87
+ setKeyframe -time 1 -value 5.05208 "SingleFrame_InTheMiddle.tx";
88
+ setKeyframe -time 1 -value 2.86458 "SingleFrame_InTheMiddle.ty";
89
+ select -r TracksperantoImagePlane Parabolic_1_from_top_left Parabolic_2_from_bottom_right SingleFrame_InTheMiddle;
90
90
  group -name TracksperantoGroup; xform -os -piv 0 0 0;
@@ -39,5 +39,5 @@
39
39
  1 18 -1.4222222222 -0.2800000000 0.0857140000
40
40
  1 19 -1.6000000000 -0.6200000000 0.0904760000
41
41
  1 20 -1.7777777778 -1.0000000000 0.0952380000
42
- # Name SingleFrame
42
+ # Name SingleFrame_InTheMiddle
43
43
  2 0 0.0185185185 0.0185185185 0.0000000000
@@ -39,5 +39,5 @@
39
39
  1 18 -1.4240000000 -0.2800000000 0.0857140000
40
40
  1 19 -1.6020000000 -0.6200000000 0.0904760000
41
41
  1 20 -1.7800000000 -1.0000000000 0.0952380000
42
- # Name SingleFrame
42
+ # Name SingleFrame_InTheMiddle
43
43
  2 0 0.0185416667 0.0185185185 0.0000000000
@@ -31,7 +31,7 @@ Tracker3 {
31
31
 
32
32
  Tracker3 {
33
33
  track1 {{curve i x1 970.0000} {curve i x1 550.0000}}
34
- name SingleFrame
34
+ name SingleFrame_InTheMiddle
35
35
  xpos 0
36
36
  ypos 90
37
37
  }
@@ -48,7 +48,7 @@
48
48
  21 0.000 0.000 0.119
49
49
 
50
50
 
51
- "SingleFrame"
51
+ "SingleFrame_InTheMiddle"
52
52
  1
53
53
  1
54
54
  1 970.000 550.000 0.000
@@ -46,6 +46,6 @@
46
46
  20 0.000 0.000 0.119
47
47
 
48
48
 
49
- "SingleFrame"
49
+ "SingleFrame_InTheMiddle"
50
50
  1
51
51
  0 970.000 550.000 0.000
@@ -48,7 +48,7 @@
48
48
  20 0.000 0.000 0.119
49
49
 
50
50
 
51
- "SingleFrame"
51
+ "SingleFrame_InTheMiddle"
52
52
  "Primary"
53
53
  1
54
54
  0 970.000 550.000 0.000
@@ -48,7 +48,7 @@ trackers << Tracksperanto::Tracker.new(:name => "Parabolic_2_from_bottom_right")
48
48
  t.keyframe!(:frame => 20, :abs_x => 0.00000, :abs_y => 0.00000, :residual => 0.95238)
49
49
  end
50
50
 
51
- trackers << Tracksperanto::Tracker.new(:name => "SingleFrame") do |t|
51
+ trackers << Tracksperanto::Tracker.new(:name => "SingleFrame_InTheMiddle") do |t|
52
52
  t.keyframe!(:frame => 0, :abs_x => 970.00000, :abs_y => 550.00000, :residual => 0.00000)
53
53
  end
54
54
 
@@ -42,7 +42,7 @@ TrackName Parabolic_2_from_bottom_right
42
42
  20.00 96.000 205.200 0.095
43
43
  21.00 0.000 0.000 0.048
44
44
 
45
- TrackName SingleFrame
45
+ TrackName SingleFrame_InTheMiddle
46
46
  Frame X Y Correlation
47
47
  1.00 970.000 550.000 1.000
48
48
 
@@ -36,4 +36,4 @@ Parabolic2FromBottomRight 17 -0.700000 -0.020000 7
36
36
  Parabolic2FromBottomRight 18 -0.800000 0.280000 7
37
37
  Parabolic2FromBottomRight 19 -0.900000 0.620000 7
38
38
  Parabolic2FromBottomRight 20 -1.000000 1.000000 7
39
- SingleFrame 0 0.010417 -0.018519 15
39
+ SingleFrameInTheMiddle 0 0.010417 -0.018519 15
@@ -0,0 +1,102 @@
1
+ Application.CreatePrim("Grid", "MeshSurface", "", "")
2
+ Application.SetValue("grid.Name", "ImagePlane", "")
3
+ Application.SetValue("ImagePlane.grid.ulength", 10.00000, "")
4
+ Application.SetValue("ImagePlane.grid.vlength", 5.62500, "")
5
+ Application.Rotate("", 90, 0, 0, "siRelative", "siLocal", "siObj", "siXYZ", "", "", "", "", "", "", "", 0, "")
6
+ # Data for tracker Parabolic_1_from_top_left
7
+ Application.GetPrim("Null", "", "", "")
8
+ Application.SetValue("null.Name", "Parabolic_1_from_top_left", "")
9
+ Application.SelectObj("Parabolic_1_from_top_left", "", True)
10
+ Application.Translate("", -5.00000, 2.81250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
11
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 1, "", "", "", False, "")
12
+ Application.Translate("", -4.50000, 1.74375, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
13
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 2, "", "", "", False, "")
14
+ Application.Translate("", -4.00000, 0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
15
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 3, "", "", "", False, "")
16
+ Application.Translate("", -3.50000, -0.05625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
17
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 4, "", "", "", False, "")
18
+ Application.Translate("", -3.00000, -0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
19
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 5, "", "", "", False, "")
20
+ Application.Translate("", -2.50000, -1.40625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
21
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 6, "", "", "", False, "")
22
+ Application.Translate("", -2.00000, -1.91250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
23
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 7, "", "", "", False, "")
24
+ Application.Translate("", -1.50000, -2.30625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
25
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 8, "", "", "", False, "")
26
+ Application.Translate("", -1.00000, -2.58750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
27
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 9, "", "", "", False, "")
28
+ Application.Translate("", -0.50000, -2.75625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
29
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 10, "", "", "", False, "")
30
+ Application.Translate("", 1.00000, -2.58750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
31
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 13, "", "", "", False, "")
32
+ Application.Translate("", 1.50000, -2.30625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
33
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 14, "", "", "", False, "")
34
+ Application.Translate("", 2.00000, -1.91250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
35
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 15, "", "", "", False, "")
36
+ Application.Translate("", 2.50000, -1.40625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
37
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 16, "", "", "", False, "")
38
+ Application.Translate("", 3.00000, -0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
39
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 17, "", "", "", False, "")
40
+ Application.Translate("", 3.50000, -0.05625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
41
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 18, "", "", "", False, "")
42
+ Application.Translate("", 4.00000, 0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
43
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 19, "", "", "", False, "")
44
+ Application.Translate("", 4.50000, 1.74375, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
45
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 20, "", "", "", False, "")
46
+ Application.Translate("", 5.00000, 2.81250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
47
+ Application.SaveKeyOnKeyable("Parabolic_1_from_top_left", 21, "", "", "", False, "")
48
+ # Data for tracker Parabolic_2_from_bottom_right
49
+ Application.GetPrim("Null", "", "", "")
50
+ Application.SetValue("null.Name", "Parabolic_2_from_bottom_right", "")
51
+ Application.SelectObj("Parabolic_2_from_bottom_right", "", True)
52
+ Application.Translate("", 5.00000, -2.81250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
53
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 1, "", "", "", False, "")
54
+ Application.Translate("", 4.50000, -1.74375, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
55
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 2, "", "", "", False, "")
56
+ Application.Translate("", 4.00000, -0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
57
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 3, "", "", "", False, "")
58
+ Application.Translate("", 3.50000, 0.05625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
59
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 4, "", "", "", False, "")
60
+ Application.Translate("", 3.00000, 0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
61
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 5, "", "", "", False, "")
62
+ Application.Translate("", 2.50000, 1.40625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
63
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 6, "", "", "", False, "")
64
+ Application.Translate("", 2.00000, 1.91250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
65
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 7, "", "", "", False, "")
66
+ Application.Translate("", 1.50000, 2.30625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
67
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 8, "", "", "", False, "")
68
+ Application.Translate("", 1.00000, 2.58750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
69
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 9, "", "", "", False, "")
70
+ Application.Translate("", 0.50000, 2.75625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
71
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 10, "", "", "", False, "")
72
+ Application.Translate("", -1.00000, 2.58750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
73
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 13, "", "", "", False, "")
74
+ Application.Translate("", -1.50000, 2.30625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
75
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 14, "", "", "", False, "")
76
+ Application.Translate("", -2.00000, 1.91250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
77
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 15, "", "", "", False, "")
78
+ Application.Translate("", -2.50000, 1.40625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
79
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 16, "", "", "", False, "")
80
+ Application.Translate("", -3.00000, 0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
81
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 17, "", "", "", False, "")
82
+ Application.Translate("", -3.50000, 0.05625, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
83
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 18, "", "", "", False, "")
84
+ Application.Translate("", -4.00000, -0.78750, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
85
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 19, "", "", "", False, "")
86
+ Application.Translate("", -4.50000, -1.74375, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
87
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 20, "", "", "", False, "")
88
+ Application.Translate("", -5.00000, -2.81250, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
89
+ Application.SaveKeyOnKeyable("Parabolic_2_from_bottom_right", 21, "", "", "", False, "")
90
+ # Data for tracker SingleFrame_InTheMiddle
91
+ Application.GetPrim("Null", "", "", "")
92
+ Application.SetValue("null.Name", "SingleFrame_InTheMiddle", "")
93
+ Application.SelectObj("SingleFrame_InTheMiddle", "", True)
94
+ Application.Translate("", 0.05208, 0.05208, 0, "siAbsolute", "siView", "siObj", "siXYZ", "", "", "", "", "", "", "", "", "", 0, "")
95
+ Application.SaveKeyOnKeyable("SingleFrame_InTheMiddle", 1, "", "", "", False, "")
96
+ Application.DeselectAll()
97
+ Application.AddToSelection("ImagePlane", "", "")
98
+ Application.AddToSelection("Parabolic_1_from_top_left", "", "")
99
+ Application.AddToSelection("Parabolic_2_from_bottom_right", "", "")
100
+ Application.AddToSelection("SingleFrame_InTheMiddle", "", "")
101
+ Application.CreateModel("", "", "", "")
102
+ Application.SetValue("Model.Name", "Tracksperanto", "")
@@ -41,4 +41,4 @@ Parabolic_2_from_bottom_right 17 288.000 530.200
41
41
  Parabolic_2_from_bottom_right 18 192.000 692.200
42
42
  Parabolic_2_from_bottom_right 19 96.000 875.800
43
43
  Parabolic_2_from_bottom_right 20 0.000 1081.000
44
- SingleFrame 0 970.000 531.000
44
+ SingleFrame_InTheMiddle 0 970.000 531.000
@@ -43,7 +43,7 @@ Parabolic_2_from_bottom_right
43
43
  19 192.000000000000000 388.800000000000011
44
44
  20 96.000000000000000 205.199999999999989
45
45
  21 0.000000000000000 0.000000000000000
46
- SingleFrame
46
+ SingleFrame_InTheMiddle
47
47
  0
48
48
  1
49
49
  1 970.000000000000000 550.000000000000000
@@ -39,6 +39,6 @@ Parabolic_2_from_bottom_right
39
39
  19 192.000 388.800
40
40
  20 96.000 205.200
41
41
  21 0.000 0.000
42
- SingleFrame
42
+ SingleFrame_InTheMiddle
43
43
  1 970.000 550.000
44
44
 
@@ -46,7 +46,7 @@ pointTrack "Parabolic_2_from_bottom_right" rgb( 255 0 0 )
46
46
  20 96.000 874.800 p+( 0.095240 )
47
47
  21 0.000 1080.000 p+( 0.047620 )
48
48
  }
49
- pointTrack "SingleFrame" rgb( 255 0 0 )
49
+ pointTrack "SingleFrame_InTheMiddle" rgb( 255 0 0 )
50
50
  {
51
51
  1 970.000 530.000 ki( 0.8 ) s( 66 66 64 64 ) p( 24 24 25 25 )
52
52
  }
@@ -6,7 +6,6 @@ class RubyExportTest < Test::Unit::TestCase
6
6
  P = File.dirname(__FILE__) + "/samples/ref_Ruby.rb"
7
7
 
8
8
  def test_export_output_written
9
- create_reference_output Tracksperanto::Export::Ruby, P
10
9
  ensure_same_output Tracksperanto::Export::Ruby, P
11
10
  end
12
11
 
@@ -0,0 +1,17 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__)) + '/../helper'
3
+
4
+ class XSIExportTest < Test::Unit::TestCase
5
+ include ParabolicTracks
6
+
7
+ P_XSI = File.dirname(__FILE__) + "/samples/ref_XSI.py"
8
+
9
+ def test_export_output_written
10
+ ensure_same_output Tracksperanto::Export::XSI, P_XSI
11
+ end
12
+
13
+ def test_exporter_meta
14
+ assert_equal "xsi_nulls.py", Tracksperanto::Export::XSI.desc_and_extension
15
+ assert_equal "Autodesk Softimage nulls Python script", Tracksperanto::Export::XSI.human_name
16
+ end
17
+ end
data/test/helper.rb CHANGED
@@ -81,7 +81,7 @@ module ParabolicTracks
81
81
  t.keyframe!(:frame => 20, :abs_x => 0.00000, :abs_y => 0.00000, :residual => 0.95238)
82
82
  end
83
83
 
84
- SINGLE_FRAME_TRACK = Tracksperanto::Tracker.new(:name => "SingleFrame") do |t|
84
+ SINGLE_FRAME_TRACK = Tracksperanto::Tracker.new(:name => "SingleFrame_InTheMiddle") do |t|
85
85
  t.keyframe!(:frame => 0, :abs_x => 970.00000, :abs_y => 550.00000, :residual => 0.00000)
86
86
  end
87
87
 
@@ -91,6 +91,7 @@ module ParabolicTracks
91
91
  yield(x) if block_given?
92
92
  export_parabolics_with(x)
93
93
  end
94
+ flunk "The test output was overwritten, so this test is meaningless"
94
95
  end
95
96
 
96
97
  def assert_same_buffer(ref_buffer, actual_buffer, message = "The line should be identical")
@@ -102,6 +103,15 @@ module ParabolicTracks
102
103
  end
103
104
 
104
105
  def ensure_same_output(exporter_klass, reference_path, message = "The line should be identical")
106
+ # If we need to update ALL the references at once
107
+ if ENV['TRACKSPERANTO_OVERWRITE_ALL_TEST_DATA']
108
+ STDERR.puts "Achtung! Overwriting the file at #{reference_path} with the test output for now"
109
+ create_reference_output(exporter_klass, reference_path) do | x |
110
+ yield(x) if block_given?
111
+ end
112
+ return
113
+ end
114
+
105
115
  io = StringIO.new
106
116
  x = exporter_klass.new(io)
107
117
  yield(x) if block_given?
@@ -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 or Reconcile3D nodes", i.human_name
9
+ assert_equal "Nuke .nk script file with Tracker, Reconcile3D and PlanarTracker nodes", i.human_name
10
10
  assert !i.autodetects_size?
11
11
  end
12
12
 
data/test/test_cli.rb CHANGED
@@ -40,7 +40,7 @@ class TestCli < Test::Unit::TestCase
40
40
  flm.stabilizer flm_3de_v3.txt flm_3de_v4.txt flm_boujou_text.txt flm_flame.stabilizer
41
41
  flm_matchmover.rz2 flm_mayalive.txt flm_nuke.nk flm_pftrack_2011_pfmatchit.txt flm_pftrack_v4.2dt
42
42
  flm_pftrack_v5.2dt flm_shake_trackers.txt flm_syntheyes_2dt.txt flm_flame_cornerpin.stabilizer
43
- flm_tracksperanto_ruby.rb flm_mayaLocators.ma flm_createNulls.jsx
43
+ flm_tracksperanto_ruby.rb flm_mayaLocators.ma flm_createNulls.jsx flm_xsi_nulls.py
44
44
  )
45
45
  assert_match /Found and converted 1 trackers with 232 keyframes\./, o, "Should have output coversion statistics"
46
46
  assert_same_set fs, Dir.entries(TEMP_DIR)
@@ -90,7 +90,7 @@ class TestCli < Test::Unit::TestCase
90
90
  assert_match /There were no trackers exported/, results[-1] # STDERR
91
91
  end
92
92
 
93
- # We use this instead of assert_equals for arrays since different filesystems
93
+ # We use this instead of assert_equals for arrays of file names since different filesystems
94
94
  # return files in different order
95
95
  def assert_same_set(expected_enum, enum, message = "Should be the same set")
96
96
  assert_equal Set.new(expected_enum), Set.new(enum), message
@@ -71,6 +71,13 @@ class TestPipeline < Test::Unit::TestCase
71
71
  assert_raise(Tracksperanto::Pipeline::EmptySourceFileError) { pipeline.run(empty_file_path) }
72
72
  end
73
73
 
74
+ def test_run_crashes_with_no_trackers
75
+ empty_file_path = "./input_empty.stabilizer"
76
+ f = File.open(empty_file_path, "w"){|f| f.write('xx') }
77
+ pipeline = Tracksperanto::Pipeline::Base.new
78
+ assert_raise(Tracksperanto::Pipeline::NoTrackersRecoveredError) { pipeline.run(empty_file_path) }
79
+ end
80
+
74
81
  def test_middleware_initialization_from_tuples
75
82
  create_stabilizer_file
76
83
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "tracksperanto"
8
- s.version = "2.10.0"
8
+ s.version = "2.11.0"
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 = "2012-05-30"
12
+ s.date = "2012-07-06"
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"]
@@ -43,6 +43,7 @@ Gem::Specification.new do |s|
43
43
  "lib/export/ruby.rb",
44
44
  "lib/export/shake_text.rb",
45
45
  "lib/export/syntheyes.rb",
46
+ "lib/export/xsi.rb",
46
47
  "lib/import/base.rb",
47
48
  "lib/import/boujou.rb",
48
49
  "lib/import/equalizer3.rb",
@@ -109,6 +110,7 @@ Gem::Specification.new do |s|
109
110
  "test/export/samples/ref_Ruby.rb",
110
111
  "test/export/samples/ref_ShakeText.txt",
111
112
  "test/export/samples/ref_Syntheyes.txt",
113
+ "test/export/samples/ref_XSI.py",
112
114
  "test/export/samples/ref_boujou.txt",
113
115
  "test/export/samples/ref_equalizer.txt",
114
116
  "test/export/samples/ref_equalizer3.txt",
@@ -132,6 +134,7 @@ Gem::Specification.new do |s|
132
134
  "test/export/test_ruby_export.rb",
133
135
  "test/export/test_shake_export.rb",
134
136
  "test/export/test_syntheyes_export.rb",
137
+ "test/export/test_xsi_python_export.rb",
135
138
  "test/helper.rb",
136
139
  "test/import/README_SAMPLES.txt",
137
140
  "test/import/test_3de_import.rb",
@@ -186,7 +189,7 @@ Gem::Specification.new do |s|
186
189
  s.homepage = "http://guerilla-di.org/tracksperanto"
187
190
  s.licenses = ["MIT"]
188
191
  s.require_paths = ["lib"]
189
- s.rubygems_version = "1.8.15"
192
+ s.rubygems_version = "1.8.24"
190
193
  s.summary = "A universal 2D tracks converter"
191
194
 
192
195
  if s.respond_to? :specification_version then
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: 2.10.0
4
+ version: 2.11.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-30 00:00:00.000000000 Z
12
+ date: 2012-07-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: obuf
16
- requirement: &81500 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: 1.1.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *81500
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.0
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: progressive_io
27
- requirement: &80900 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
@@ -32,10 +37,15 @@ dependencies:
32
37
  version: '1.0'
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *80900
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.0'
36
46
  - !ruby/object:Gem::Dependency
37
47
  name: flame_channel_parser
38
- requirement: &80430 !ruby/object:Gem::Requirement
48
+ requirement: !ruby/object:Gem::Requirement
39
49
  none: false
40
50
  requirements:
41
51
  - - ~>
@@ -43,21 +53,31 @@ dependencies:
43
53
  version: '4.0'
44
54
  type: :runtime
45
55
  prerelease: false
46
- version_requirements: *80430
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '4.0'
47
62
  - !ruby/object:Gem::Dependency
48
63
  name: progressbar
49
- requirement: &79900 !ruby/object:Gem::Requirement
64
+ requirement: !ruby/object:Gem::Requirement
50
65
  none: false
51
66
  requirements:
52
- - - =
67
+ - - '='
53
68
  - !ruby/object:Gem::Version
54
69
  version: 0.10.0
55
70
  type: :runtime
56
71
  prerelease: false
57
- version_requirements: *79900
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.10.0
58
78
  - !ruby/object:Gem::Dependency
59
79
  name: update_hints
60
- requirement: &79370 !ruby/object:Gem::Requirement
80
+ requirement: !ruby/object:Gem::Requirement
61
81
  none: false
62
82
  requirements:
63
83
  - - ~>
@@ -65,10 +85,15 @@ dependencies:
65
85
  version: '1.0'
66
86
  type: :runtime
67
87
  prerelease: false
68
- version_requirements: *79370
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '1.0'
69
94
  - !ruby/object:Gem::Dependency
70
95
  name: approximately
71
- requirement: &79050 !ruby/object:Gem::Requirement
96
+ requirement: !ruby/object:Gem::Requirement
72
97
  none: false
73
98
  requirements:
74
99
  - - ! '>='
@@ -76,10 +101,15 @@ dependencies:
76
101
  version: '0'
77
102
  type: :development
78
103
  prerelease: false
79
- version_requirements: *79050
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
80
110
  - !ruby/object:Gem::Dependency
81
111
  name: jeweler
82
- requirement: &78640 !ruby/object:Gem::Requirement
112
+ requirement: !ruby/object:Gem::Requirement
83
113
  none: false
84
114
  requirements:
85
115
  - - ! '>='
@@ -87,10 +117,15 @@ dependencies:
87
117
  version: '0'
88
118
  type: :development
89
119
  prerelease: false
90
- version_requirements: *78640
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
91
126
  - !ruby/object:Gem::Dependency
92
127
  name: rake
93
- requirement: &78050 !ruby/object:Gem::Requirement
128
+ requirement: !ruby/object:Gem::Requirement
94
129
  none: false
95
130
  requirements:
96
131
  - - ! '>='
@@ -98,10 +133,15 @@ dependencies:
98
133
  version: '0'
99
134
  type: :development
100
135
  prerelease: false
101
- version_requirements: *78050
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
102
142
  - !ruby/object:Gem::Dependency
103
143
  name: flexmock
104
- requirement: &524110 !ruby/object:Gem::Requirement
144
+ requirement: !ruby/object:Gem::Requirement
105
145
  none: false
106
146
  requirements:
107
147
  - - ~>
@@ -109,10 +149,15 @@ dependencies:
109
149
  version: '0.8'
110
150
  type: :development
111
151
  prerelease: false
112
- version_requirements: *524110
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: '0.8'
113
158
  - !ruby/object:Gem::Dependency
114
159
  name: cli_test
115
- requirement: &522630 !ruby/object:Gem::Requirement
160
+ requirement: !ruby/object:Gem::Requirement
116
161
  none: false
117
162
  requirements:
118
163
  - - ~>
@@ -120,7 +165,12 @@ dependencies:
120
165
  version: '1.0'
121
166
  type: :development
122
167
  prerelease: false
123
- version_requirements: *522630
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: '1.0'
124
174
  description: Converts 2D track exports between different apps like Flame, MatchMover,
125
175
  PFTrack...
126
176
  email: me@julik.nl
@@ -156,6 +206,7 @@ files:
156
206
  - lib/export/ruby.rb
157
207
  - lib/export/shake_text.rb
158
208
  - lib/export/syntheyes.rb
209
+ - lib/export/xsi.rb
159
210
  - lib/import/base.rb
160
211
  - lib/import/boujou.rb
161
212
  - lib/import/equalizer3.rb
@@ -222,6 +273,7 @@ files:
222
273
  - test/export/samples/ref_Ruby.rb
223
274
  - test/export/samples/ref_ShakeText.txt
224
275
  - test/export/samples/ref_Syntheyes.txt
276
+ - test/export/samples/ref_XSI.py
225
277
  - test/export/samples/ref_boujou.txt
226
278
  - test/export/samples/ref_equalizer.txt
227
279
  - test/export/samples/ref_equalizer3.txt
@@ -245,6 +297,7 @@ files:
245
297
  - test/export/test_ruby_export.rb
246
298
  - test/export/test_shake_export.rb
247
299
  - test/export/test_syntheyes_export.rb
300
+ - test/export/test_xsi_python_export.rb
248
301
  - test/helper.rb
249
302
  - test/import/README_SAMPLES.txt
250
303
  - test/import/test_3de_import.rb
@@ -310,7 +363,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
310
363
  version: '0'
311
364
  segments:
312
365
  - 0
313
- hash: -819741475
366
+ hash: -2148576341251209313
314
367
  required_rubygems_version: !ruby/object:Gem::Requirement
315
368
  none: false
316
369
  requirements:
@@ -319,7 +372,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
319
372
  version: '0'
320
373
  requirements: []
321
374
  rubyforge_project:
322
- rubygems_version: 1.8.15
375
+ rubygems_version: 1.8.24
323
376
  signing_key:
324
377
  specification_version: 3
325
378
  summary: A universal 2D tracks converter