tracksperanto 2.10.0 → 2.11.0

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 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