tracksperanto 2.12.0 → 3.0.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/DEVELOPER_DOCS.rdoc +15 -8
- data/History.txt +21 -14
- data/Rakefile +1 -0
- data/bin/tracksperanto +30 -29
- data/lib/export/flame_stabilizer_cornerpin.rb +4 -2
- data/lib/export/pfmatchit.rb +8 -1
- data/lib/export/pftrack.rb +8 -1
- data/lib/import/pftrack.rb +4 -1
- data/lib/import/syntheyes.rb +2 -2
- data/lib/pipeline/base.rb +13 -13
- data/lib/{middleware → tools}/base.rb +7 -7
- data/lib/{middleware → tools}/crop.rb +3 -3
- data/lib/{middleware → tools}/flip.rb +2 -2
- data/lib/{middleware → tools}/flop.rb +2 -2
- data/lib/{middleware → tools}/golden.rb +2 -2
- data/lib/{middleware → tools}/length_cutoff.rb +2 -2
- data/lib/{middleware → tools}/lens_disto.rb +2 -2
- data/lib/{middleware → tools}/lerp.rb +2 -2
- data/lib/{middleware → tools}/lint.rb +1 -1
- data/lib/{middleware → tools}/move_to_first.rb +3 -3
- data/lib/{middleware → tools}/pad.rb +2 -2
- data/lib/{middleware → tools}/prefix.rb +2 -2
- data/lib/{middleware → tools}/reformat.rb +3 -3
- data/lib/{middleware → tools}/scaler.rb +1 -1
- data/lib/{middleware → tools}/shift.rb +2 -2
- data/lib/{middleware → tools}/slipper.rb +1 -1
- data/lib/tools/start_trim.rb +17 -0
- data/lib/tracksperanto/pf_coords.rb +9 -0
- data/lib/tracksperanto/simple_export.rb +1 -1
- data/lib/tracksperanto/uv_coordinates.rb +15 -13
- data/lib/tracksperanto.rb +16 -15
- data/test/export/samples/ref_PFMatchit.2dt +39 -39
- data/test/export/samples/ref_PFTrack.2dt +39 -39
- data/test/export/samples/ref_PFTrack5.2dt +39 -39
- data/test/export/samples/ref_Syntheyes.txt +39 -39
- data/test/import/test_pftrack_import.rb +5 -5
- data/test/import/test_shake_script_import.rb +9 -1
- data/test/import/test_syntheyes_import.rb +3 -3
- data/test/subpixel/Flame_Smk2013_SubpixSample.stabilizer +310 -0
- data/test/subpixel/julik_pftrack.txt +14 -0
- data/test/subpixel/shake_subpix_v01.shk +308 -0
- data/test/subpixel/subpix_import_test.rb +75 -0
- data/test/subpixel/subpixel_grid.ifl +1 -0
- data/test/subpixel/subpixel_grid.sni +0 -0
- data/test/subpixel/subpixel_grid.tif +0 -0
- data/test/subpixel/sy_subpix_2dpaths.txt +4 -0
- data/test/test_const_name.rb +2 -2
- data/test/test_pipeline.rb +10 -10
- data/test/test_tracksperanto.rb +11 -11
- data/test/test_uv_coords.rb +29 -0
- data/test/{middleware → tools}/test_crop_middleware.rb +4 -4
- data/test/{middleware → tools}/test_flip_middleware.rb +3 -3
- data/test/{middleware → tools}/test_flop_middleware.rb +3 -3
- data/test/{middleware → tools}/test_golden_middleware.rb +3 -3
- data/test/{middleware → tools}/test_length_cutoff_middleware.rb +5 -5
- data/test/{middleware → tools}/test_lens_middleware.rb +9 -9
- data/test/{middleware → tools}/test_lerp_middleware.rb +3 -3
- data/test/{middleware → tools}/test_lint_middleware.rb +11 -11
- data/test/{middleware → tools}/test_move_to_first_frame_middleware.rb +3 -3
- data/test/{middleware → tools}/test_pad_middleware.rb +4 -4
- data/test/{middleware → tools}/test_prefix.rb +5 -5
- data/test/{middleware → tools}/test_reformat_middleware.rb +5 -5
- data/test/{middleware → tools}/test_scaler_middleware.rb +7 -7
- data/test/{middleware → tools}/test_shift_middleware.rb +4 -4
- data/test/{middleware → tools}/test_slip_middleware.rb +5 -5
- data/test/{middleware → tools}/test_start_trim_middleware.rb +3 -3
- data/tracksperanto.gemspec +45 -35
- metadata +46 -36
- data/lib/middleware/start_trim.rb +0 -17
data/DEVELOPER_DOCS.rdoc
CHANGED
@@ -18,6 +18,13 @@ in the Gemfile plus Bundler. Please develop against the git repo checkout since
|
|
18
18
|
* Carry your development, in your own branch or feature branch
|
19
19
|
* File a pull request or send a patch to info at guerilla-di.org
|
20
20
|
|
21
|
+
=== Internal tracker representation
|
22
|
+
|
23
|
+
The trackers are represented by Tracker objects, which work like addressable hashes per frame number. The Tracker objects
|
24
|
+
contain Keyframe objects, and those in turn contain coordinates. The coordinates are stored in absolute pixels, relative to
|
25
|
+
the zero coordinate in the lower left corner. The absolute left/bottom of the image has coordinates 0,0 (at the lower left corner of the
|
26
|
+
first pixel) and 0.5x0.5 in the middle of the leftmost lower pixel.
|
27
|
+
|
21
28
|
=== Importing your own formats
|
22
29
|
|
23
30
|
You can easily write a Tracksperanto import module - refer to Tracksperanto::Import::Base
|
@@ -33,14 +40,14 @@ the exporter should work with streams (smaller parts of the file being exported
|
|
33
40
|
|
34
41
|
=== Ading your own processing steps
|
35
42
|
|
36
|
-
You probably want to write a
|
37
|
-
or their data. A
|
38
|
-
modules or each other, so you can stack different
|
43
|
+
You probably want to write a Tool (consult the Tracksperanto::Tool::Base docs) if you need some processing applied to the tracks
|
44
|
+
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
|
45
|
+
modules or each other, so you can stack different tool modules together (like "scale first, then move").
|
39
46
|
|
40
47
|
=== Writing your own processing routines
|
41
48
|
|
42
49
|
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
|
43
|
-
input format, allocating output files and building a chain of
|
50
|
+
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
|
44
51
|
to write your own Pipeline class or reimplement parts of it.
|
45
52
|
|
46
53
|
=== Reporting status from long-running operations
|
@@ -74,11 +81,11 @@ the software user-friendly. A well-behaved Tracksperanto module should manage it
|
|
74
81
|
destination_file = File.open("exported_file.other", "wb")
|
75
82
|
some_exporter = Tracksperanto.get_exporter("flamestabilizer").new(destination_file)
|
76
83
|
|
77
|
-
# Now add some
|
78
|
-
scaler =
|
79
|
-
# ... and a slip.
|
84
|
+
# Now add some tools, for example a Scale
|
85
|
+
scaler = Tool::Scaler.new(some_exporter, :x_factor => 2)
|
86
|
+
# ... and a slip. Tools wrap exporters and other tools, so you can chain them
|
80
87
|
# ad nauseam
|
81
|
-
slipper =
|
88
|
+
slipper = Tool::Slipper.new(scaler, :offset => 2)
|
82
89
|
|
83
90
|
# Now when we send export commands to the Slipper it will play them through
|
84
91
|
# to the Scaler and the Scaler in turn will send commands to the exporter.
|
data/History.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 3.0.0
|
2
|
+
|
3
|
+
* Middleware renamed to Tools
|
4
|
+
* Multiple subpixel accuracy tests added
|
5
|
+
* Subpixel accuracy fixed for Syntheyes modules
|
6
|
+
* Subpixel accuracy fixed for PFTrack modules
|
7
|
+
|
1
8
|
=== 2.12.0
|
2
9
|
|
3
10
|
* Add an export module for Nuke's CameraTracker node. This is just like the Shake format, except that tracker names have to be special.
|
@@ -21,7 +28,7 @@
|
|
21
28
|
|
22
29
|
=== 2.9.9
|
23
30
|
|
24
|
-
* Add lens distortion
|
31
|
+
* Add lens distortion tool. Adds the possibility to remove or add Syntheyes lens distortion to your plates.
|
25
32
|
|
26
33
|
=== 2.9.8
|
27
34
|
|
@@ -34,7 +41,7 @@
|
|
34
41
|
=== 2.9.6
|
35
42
|
|
36
43
|
* Add Nuke Reconcile3D support
|
37
|
-
* Add
|
44
|
+
* Add Tool::Base.parameters for automatic GUI building
|
38
45
|
|
39
46
|
=== 2.9.5
|
40
47
|
|
@@ -71,7 +78,7 @@
|
|
71
78
|
|
72
79
|
=== 2.8.5
|
73
80
|
|
74
|
-
* Add Pad and Crop
|
81
|
+
* Add Pad and Crop tools for fixing botched telecine and anamorphic Alexa
|
75
82
|
|
76
83
|
=== 2.8.2
|
77
84
|
|
@@ -85,7 +92,7 @@
|
|
85
92
|
=== 2.8.1
|
86
93
|
|
87
94
|
* Fix the bug that MatchMover importer would always assume the sequence starting on frame 1
|
88
|
-
* Fix the bug that Lint
|
95
|
+
* Fix the bug that Lint tool would raise when the export was started from negative frame offsets
|
89
96
|
|
90
97
|
=== 2.8.0
|
91
98
|
|
@@ -193,7 +200,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
193
200
|
|
194
201
|
=== 2.0.2
|
195
202
|
* Compatible with Ruby 1.9.2
|
196
|
-
* Scaler
|
203
|
+
* Scaler tool now supports negative scaling factors
|
197
204
|
|
198
205
|
=== 2.0.0
|
199
206
|
* Bugfix for PFTrack exports to contain cross-platform linebreaks (rn instead of n)
|
@@ -208,7 +215,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
208
215
|
* Very minor changes and improvements
|
209
216
|
* The app will now tell you when you try to feed it an empty file
|
210
217
|
* Change Synetheyes exports to start with a standard frame and not a keyframe to make 1-frame trackers work
|
211
|
-
* Adds a flip
|
218
|
+
* Adds a flip tool to mirror a tracked comp
|
212
219
|
|
213
220
|
=== 1.9.6
|
214
221
|
|
@@ -241,7 +248,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
241
248
|
=== 1.9.0
|
242
249
|
|
243
250
|
* Use proper progress bars
|
244
|
-
* Allow proper chaining of
|
251
|
+
* Allow proper chaining of tools in the commandline app - you can now apply many tools of the same nature in chain, and they will be ordered correctly
|
245
252
|
* Small rewrites to Pipeline::Base (changes API slightly - please consult the docs)
|
246
253
|
|
247
254
|
=== 1.8.4
|
@@ -270,7 +277,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
270
277
|
* Introduce an intentional gap in the reference exports to test trackers with gaps
|
271
278
|
* Export Syntheyes paths as normal frames, not as keyframes. This produces better solves by not overconstraining the solver
|
272
279
|
(Without this TransitionFrms, a crucial parameter in SY, seizes to work)
|
273
|
-
* Add a LengthCutoff
|
280
|
+
* Add a LengthCutoff tool that allows you to remove trackers that have less than X keyframes in them from the export
|
274
281
|
|
275
282
|
=== 1.7.3
|
276
283
|
|
@@ -278,7 +285,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
278
285
|
|
279
286
|
=== 1.7.2
|
280
287
|
|
281
|
-
* Add a Lerp
|
288
|
+
* Add a Lerp tool that linearly interpolates missing keyframes (USE CAREFULLY!)
|
282
289
|
* Prevent the Shake lexer from walking into the woods on files that are certainly wrong
|
283
290
|
* Export proper project length with Nuke scripts
|
284
291
|
* Ensure preamble for Nuke exports does not get overriden in width/height
|
@@ -322,7 +329,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
322
329
|
|
323
330
|
=== 1.6.2
|
324
331
|
|
325
|
-
* Fixes the Reformat
|
332
|
+
* Fixes the Reformat tool to not suppress the end_export call. Crucial for exporters that
|
326
333
|
use end_export to finalize output
|
327
334
|
|
328
335
|
=== 1.6.0
|
@@ -332,7 +339,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
332
339
|
|
333
340
|
=== 1.5.7
|
334
341
|
|
335
|
-
* Add a Prefix
|
342
|
+
* Add a Prefix tool that prefixes tracker names
|
336
343
|
|
337
344
|
=== 1.5.6
|
338
345
|
|
@@ -350,7 +357,7 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
350
357
|
=== 1.5.2
|
351
358
|
|
352
359
|
* Fix Windows-specific issue (Tempfile-related) in the Equalizer4 exporter
|
353
|
-
* Add Export::Base#just_export and
|
360
|
+
* Add Export::Base#just_export and Tool::Base#just_export
|
354
361
|
|
355
362
|
=== 1.5.0
|
356
363
|
|
@@ -392,8 +399,8 @@ Downside: stream_parse will be deprecated. It is however still available for bac
|
|
392
399
|
|
393
400
|
* Add experimental MatchMoverPro import and export support
|
394
401
|
* Rewrite the Shake parser, support MatchMove and Stabilize nodes and many tracks per node
|
395
|
-
* Officially add and test the Reformat
|
396
|
-
* Remove the Close
|
402
|
+
* Officially add and test the Reformat tool
|
403
|
+
* Remove the Close tool and close IOs automatically at pipeline end
|
397
404
|
* Much improved documentation
|
398
405
|
* Use IO as base for all the parsers (if a parser needs a string it will have to read by himself)
|
399
406
|
* Much improved test coverage
|
data/Rakefile
CHANGED
data/bin/tracksperanto
CHANGED
@@ -22,26 +22,26 @@ def disclaimer
|
|
22
22
|
end
|
23
23
|
|
24
24
|
options = {}
|
25
|
-
$
|
25
|
+
$tools = []
|
26
26
|
writer_class_name = nil
|
27
27
|
readers = Tracksperanto.importer_names
|
28
28
|
writers = Tracksperanto.exporter_names
|
29
29
|
|
30
30
|
op = OptionParser.new
|
31
31
|
|
32
|
-
def
|
32
|
+
def tool(*name_option_and_default_value)
|
33
33
|
Proc.new do |value|
|
34
34
|
name, option, default_value = name_option_and_default_value
|
35
35
|
v = value.nil? ? default_value : value
|
36
|
-
|
37
|
-
|
36
|
+
tool_tuple = [name]
|
37
|
+
tool_tuple.push({option => v}) if option
|
38
38
|
|
39
|
-
$
|
39
|
+
$tools.push(tool_tuple)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
Tracksperanto.
|
43
|
+
def toold(name)
|
44
|
+
Tracksperanto.get_tool(name).action_description
|
45
45
|
end
|
46
46
|
|
47
47
|
def list_exporters(dest = $stderr)
|
@@ -77,43 +77,44 @@ op.on(" -w", "--width WIDTH_IN_PIXELS", Integer, "Absolute input comp width in p
|
|
77
77
|
op.on(" -h", "--height HEIGHT_IN_PIXELS", Integer, "Absolute input comp height in pixels (will try to autodetect)") {|w| options[:height] = w }
|
78
78
|
op.on(" -o", "--only EXPORTER_NAME", String, "Only export the selected format, format must be one of: #{f(writers)}") { |f| writer_class_name = f }
|
79
79
|
|
80
|
-
op.on(" -xs", "--xscale X_SCALING_FACTOR", Float,
|
80
|
+
op.on(" -xs", "--xscale X_SCALING_FACTOR", Float, toold("Scaler"), &tool("Scaler", :x_factor))
|
81
81
|
|
82
|
-
op.on(" -pad", "--pad PAD_FRACTION_VALUES_COMMA_SEPARATED", String,
|
82
|
+
op.on(" -pad", "--pad PAD_FRACTION_VALUES_COMMA_SEPARATED", String, toold("Pad")) do | pads|
|
83
83
|
left, right, top, bottom = pads.split(",").map{|e| e.to_f }
|
84
|
-
$
|
84
|
+
$tools.push(["Pad", {"left_pad" => left, "right_pad"=> right, "top_pad" => top, "bottom_pad" => bottom}])
|
85
85
|
end
|
86
86
|
|
87
87
|
op.on(" -u", "--undistort K_AND_KCUBE_COMMA_SEPARATED", String, "Remove lens distortion using the Syntheyes algorithm") do | coefficients |
|
88
88
|
k, kcube = coefficients.split(",").map{|e| e.to_f }
|
89
|
-
$
|
89
|
+
$tools.push(["LensDisto", {"k" => k, "kcube"=> kcube, "remove" => true}])
|
90
90
|
end
|
91
91
|
|
92
92
|
op.on(" -d", "--distort K_AND_KCUBE_COMMA_SEPARATED", String, "Add lens distortion using the Syntheyes algorithm") do | coefficients |
|
93
93
|
k, kcube = coefficients.split(",").map{|e| e.to_f }
|
94
|
-
$
|
94
|
+
$tools.push(["LensDisto", {"k" => k, "kcube"=> kcube, "remove" => false}])
|
95
95
|
end
|
96
96
|
|
97
|
-
op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String,
|
97
|
+
op.on(" -crop", "--crop CROP_VALUES_COMMA_SEPARATED", String, toold("Crop")) do | pads|
|
98
98
|
left, right, top, bottom = pads.split(",").map{|e| e.to_i }
|
99
|
-
$
|
99
|
+
$tools.push(["Crop", {"left" => left, "right"=> right, "top" => top, "bottom" => bottom}])
|
100
100
|
end
|
101
101
|
|
102
|
-
op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float,
|
103
|
-
op.on(" -t", "--trim", Float,
|
104
|
-
op.on(" -s", "--slip FRAMES", Integer,
|
105
|
-
op.on(" -g", "--golden",
|
106
|
-
op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer,
|
107
|
-
op.on(" -p", "--prefix PREFIX", String,
|
108
|
-
op.on("--
|
109
|
-
op.on("--
|
110
|
-
op.on("--
|
102
|
+
op.on(" -ys", "--yscale Y_SCALING_FACTOR", Float, toold("Scaler"), &tool("Scaler", :y_factor))
|
103
|
+
op.on(" -t", "--trim", Float, toold("StartTrim"), &tool("StartTrim")) # Before slip!
|
104
|
+
op.on(" -s", "--slip FRAMES", Integer, toold("Slipper"), &tool("Slipper", :slip))
|
105
|
+
op.on(" -g", "--golden", toold("Golden"), &tool("Golden"))
|
106
|
+
op.on(" -m", "--min-length LENGTH_IN_FRAMES", Integer, toold("LengthCutoff"), &tool("LengthCutoff", :min_length))
|
107
|
+
op.on(" -p", "--prefix PREFIX", String, toold("Prefix"), &tool("Prefix", :prefix))
|
108
|
+
op.on(" -as", "--autoslip", toold("MoveToFirst"), &tool("MoveToFirst"))
|
109
|
+
op.on("--lerp", toold("Lerp"), &tool("Lerp"))
|
110
|
+
op.on("--flip", toold("Flip"), &tool("Flip"))
|
111
|
+
op.on("--flop", toold("Flop"), &tool("Flop"))
|
111
112
|
|
112
113
|
# TODO - multiparameters
|
113
|
-
op.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it", &
|
114
|
-
op.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it", &
|
115
|
-
op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &
|
116
|
-
op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &
|
114
|
+
op.on(" -rx", "--reformat-x NEW_PIX_WIDTH", Integer, "Reformat the comp to this width and scale all tracks to it", &tool("Reformat", :width))
|
115
|
+
op.on(" -ry", "--reformat-y NEW_PIX_HEIGHT", Integer, "Reformat the comp to this height and scale all tracks to it", &tool("Reformat", :height))
|
116
|
+
op.on(" -xm", "--xshift X_IN_PIXELS", Float, "Move the points left or right", &tool("Shift", :x_shift))
|
117
|
+
op.on(" -ym", "--yshift Y_IN_PIXELS", Float, "Move the points up or down", &tool("Shift", :y_shift))
|
117
118
|
|
118
119
|
|
119
120
|
op.on("--list-exporters", "Show available export modules") do
|
@@ -152,7 +153,7 @@ progress = lambda do |percent,message|
|
|
152
153
|
end
|
153
154
|
|
154
155
|
begin
|
155
|
-
pipe = Tracksperanto::Pipeline::Base.new(:progress_block => progress, :
|
156
|
+
pipe = Tracksperanto::Pipeline::Base.new(:progress_block => progress, :tool_tuples => $tools)
|
156
157
|
pipe.exporters = [Tracksperanto.get_exporter(writer_class_name)] if writer_class_name
|
157
158
|
pipe.run(input_file, options)
|
158
159
|
pbar.finish
|
@@ -165,7 +166,7 @@ rescue Tracksperanto::UnknownImporterError => damn
|
|
165
166
|
$stderr.puts damn.message
|
166
167
|
list_importers($stderr)
|
167
168
|
fail "Unknown importer"
|
168
|
-
rescue Tracksperanto::
|
169
|
+
rescue Tracksperanto::UnknownToolError => damn
|
169
170
|
$stderr.puts damn.message
|
170
171
|
fail "This is a bug, please report it"
|
171
172
|
rescue Exception => damn
|
@@ -17,7 +17,7 @@ class Tracksperanto::Export::FlameStabilizerCornerpin < Tracksperanto::Export::F
|
|
17
17
|
# _______/
|
18
18
|
# |
|
19
19
|
# BL -> BR
|
20
|
-
# This "kinda
|
20
|
+
# This "kinda tool" ensures that this is indeed taking place
|
21
21
|
class Sorter < DelegateClass(Tracksperanto::Export::Base)
|
22
22
|
include Tracksperanto::SimpleExport # so that it calls OUR methods
|
23
23
|
|
@@ -68,7 +68,9 @@ class Tracksperanto::Export::FlameStabilizerCornerpin < Tracksperanto::Export::F
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
# Initialize the exporter with a preconfigured sorter around it
|
71
|
+
# Initialize the exporter with a preconfigured sorter around it.
|
72
|
+
# When this object receives the commands they will come from the Sorter instead,
|
73
|
+
# and the trackers will already be in their Z-order
|
72
74
|
def self.new(*arguments)
|
73
75
|
object = super
|
74
76
|
Sorter.new(object)
|
data/lib/export/pfmatchit.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# Export for PFMatchit
|
3
3
|
class Tracksperanto::Export::PFMatchit < Tracksperanto::Export::Base
|
4
4
|
|
5
|
+
include Tracksperanto::PFCoords
|
6
|
+
|
5
7
|
KEYFRAME_TEMPLATE = "%s %.3f %.3f %.3f"
|
6
8
|
|
7
9
|
def self.desc_and_extension
|
@@ -12,6 +14,11 @@ class Tracksperanto::Export::PFMatchit < Tracksperanto::Export::Base
|
|
12
14
|
"PFTrack2011/PFMatchit .txt file (single camera)"
|
13
15
|
end
|
14
16
|
|
17
|
+
def start_export(w, h)
|
18
|
+
@width = w
|
19
|
+
@height = h
|
20
|
+
end
|
21
|
+
|
15
22
|
def start_tracker_segment(tracker_name)
|
16
23
|
# Setup for the next tracker
|
17
24
|
@frame_count = 0
|
@@ -36,7 +43,7 @@ class Tracksperanto::Export::PFMatchit < Tracksperanto::Export::Base
|
|
36
43
|
|
37
44
|
def export_point(frame, abs_float_x, abs_float_y, float_residual)
|
38
45
|
@frame_count += 1
|
39
|
-
line = KEYFRAME_TEMPLATE % [frame_number(frame), abs_float_x, abs_float_y, float_residual / 8]
|
46
|
+
line = KEYFRAME_TEMPLATE % [frame_number(frame), to_pfcoord(abs_float_x), to_pfcoord(abs_float_y), float_residual / 8]
|
40
47
|
@tracker_io.write(line)
|
41
48
|
@tracker_io.write(linebreak)
|
42
49
|
end
|
data/lib/export/pftrack.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# Export for PFTrack .2dt files
|
3
3
|
class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
|
4
4
|
|
5
|
+
include Tracksperanto::PFCoords
|
6
|
+
|
5
7
|
KEYFRAME_TEMPLATE = "%s %.3f %.3f %.3f"
|
6
8
|
|
7
9
|
# PFtrack wants cross-platform linebreaks
|
@@ -15,6 +17,11 @@ class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
|
|
15
17
|
"PFTrack v4 .2dt file"
|
16
18
|
end
|
17
19
|
|
20
|
+
def start_export(w, h)
|
21
|
+
@width = w
|
22
|
+
@height = h
|
23
|
+
end
|
24
|
+
|
18
25
|
def start_tracker_segment(tracker_name)
|
19
26
|
# Setup for the next tracker
|
20
27
|
@frame_count = 0
|
@@ -36,7 +43,7 @@ class Tracksperanto::Export::PFTrack4 < Tracksperanto::Export::Base
|
|
36
43
|
|
37
44
|
def export_point(frame, abs_float_x, abs_float_y, float_residual)
|
38
45
|
@frame_count += 1
|
39
|
-
line = KEYFRAME_TEMPLATE % [frame, abs_float_x, abs_float_y, float_residual / 8]
|
46
|
+
line = KEYFRAME_TEMPLATE % [frame, to_pfcoord(abs_float_x), to_pfcoord(abs_float_y), float_residual / 8]
|
40
47
|
@tracker_io.write(line)
|
41
48
|
@tracker_io.write(LINEBREAK)
|
42
49
|
end
|
data/lib/import/pftrack.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# TODO: this should be rewritten as a proper state-machine parser
|
3
3
|
class Tracksperanto::Import::PFTrack < Tracksperanto::Import::Base
|
4
|
+
|
5
|
+
include Tracksperanto::PFCoords
|
6
|
+
|
4
7
|
def self.human_name
|
5
8
|
"PFTrack/PFMatchit .2dt file"
|
6
9
|
end
|
@@ -73,7 +76,7 @@ class Tracksperanto::Import::PFTrack < Tracksperanto::Import::Base
|
|
73
76
|
(1..num_of_keyframes).map do | keyframe_idx |
|
74
77
|
report_progress("Reading keyframe #{keyframe_idx} of #{num_of_keyframes} in #{t.name}")
|
75
78
|
f, x, y, residual = io.gets.chomp.split
|
76
|
-
t.keyframe!(:frame => f, :abs_x => x, :abs_y => y, :residual => residual.to_f * 8)
|
79
|
+
t.keyframe!(:frame => f, :abs_x => from_pfcoord(x), :abs_y => from_pfcoord(y), :residual => residual.to_f * 8)
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
data/lib/import/syntheyes.rb
CHANGED
@@ -20,8 +20,8 @@ class Tracksperanto::Import::Syntheyes < Tracksperanto::Import::Base
|
|
20
20
|
# Add the keyframe
|
21
21
|
k = Tracksperanto::Keyframe.new do |e|
|
22
22
|
e.frame = frame
|
23
|
-
e.abs_x = convert_from_uv(
|
24
|
-
e.abs_y = height - convert_from_uv(
|
23
|
+
e.abs_x = convert_from_uv(x, width)
|
24
|
+
e.abs_y = height - convert_from_uv(y, height) # Convert TL to BL
|
25
25
|
end
|
26
26
|
|
27
27
|
@last_tracker.push(k)
|
data/lib/pipeline/base.rb
CHANGED
@@ -31,10 +31,10 @@ module Tracksperanto::Pipeline
|
|
31
31
|
|
32
32
|
# The base pipeline is the whole process of track conversion from start to finish.
|
33
33
|
# The pipeline object organizes the import formats, scans them,
|
34
|
-
# applies the
|
34
|
+
# applies the tools. Here's how a calling sequence for a pipeline looks like:
|
35
35
|
#
|
36
36
|
# pipe = Tracksperanto::Pipeline::Base.new
|
37
|
-
# pipe.
|
37
|
+
# pipe.tool_tuples = ["Shift", {:x => 10}]
|
38
38
|
# pipe.progress_block = lambda{|percent, msg| puts("#{msg}..#{percent.to_i}%") }
|
39
39
|
# pipe.run("/tmp/shakescript.shk", :width => 720, :height => 576)
|
40
40
|
#
|
@@ -64,7 +64,7 @@ module Tracksperanto::Pipeline
|
|
64
64
|
attr_accessor :exporters
|
65
65
|
|
66
66
|
# Contains arrays of the form ["MiddewareName", {:param => value}]
|
67
|
-
attr_accessor :
|
67
|
+
attr_accessor :tool_tuples
|
68
68
|
|
69
69
|
|
70
70
|
def initialize(*any)
|
@@ -72,13 +72,13 @@ module Tracksperanto::Pipeline
|
|
72
72
|
@ios = []
|
73
73
|
end
|
74
74
|
|
75
|
-
# Will scan the
|
76
|
-
#
|
77
|
-
def
|
78
|
-
return output unless (
|
75
|
+
# Will scan the tool_tuples attribute and create a processing chain.
|
76
|
+
# Tools will be instantiated and wrap each other, starting with the first one
|
77
|
+
def wrap_output_with_tools(output)
|
78
|
+
return output unless (tool_tuples && tool_tuples.any?)
|
79
79
|
|
80
|
-
|
81
|
-
Tracksperanto.
|
80
|
+
tool_tuples.reverse.inject(output) do | wrapped, (tool_name, options) |
|
81
|
+
Tracksperanto.get_tool(tool_name).new(wrapped, options || {})
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -105,10 +105,10 @@ module Tracksperanto::Pipeline
|
|
105
105
|
mux = setup_outputs_for(from_input_file_path)
|
106
106
|
|
107
107
|
# Wrap it into a module that will prevent us from exporting invalid trackers
|
108
|
-
lint = Tracksperanto::
|
108
|
+
lint = Tracksperanto::Tool::Lint.new(mux)
|
109
109
|
|
110
|
-
# Setup
|
111
|
-
endpoint =
|
110
|
+
# Setup tools
|
111
|
+
endpoint = wrap_output_with_tools(lint)
|
112
112
|
@converted_points, @converted_keyframes = run_export(read_data, importer, endpoint)
|
113
113
|
end
|
114
114
|
|
@@ -182,7 +182,7 @@ module Tracksperanto::Pipeline
|
|
182
182
|
# Use the width and height provided by the parser itself
|
183
183
|
exporter.start_export(importer.width, importer.height)
|
184
184
|
|
185
|
-
# Now send each tracker through the
|
185
|
+
# Now send each tracker through the tool chain
|
186
186
|
obuf.each_with_index do | t, tracker_idx |
|
187
187
|
|
188
188
|
kf_weight = percent_per_tracker / t.keyframes.length
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require "forwardable"
|
3
3
|
|
4
|
-
# The base
|
5
|
-
# as an export format.
|
4
|
+
# The base tool class works just like a Tracksperanto::Export::Base, but it only wraps another exporting object and does not get registered on it's own
|
5
|
+
# as an export format. Tool can be used to massage the tracks being exported in various interesting ways - like moving the coordinates, clipping the keyframes,
|
6
6
|
# scaling the whole export or even reversing the trackers to go backwards
|
7
|
-
class Tracksperanto::
|
7
|
+
class Tracksperanto::Tool::Base
|
8
8
|
include Tracksperanto::Casts
|
9
9
|
include Tracksperanto::BlockInit
|
10
10
|
include Tracksperanto::ConstName
|
@@ -14,17 +14,17 @@ class Tracksperanto::Middleware::Base
|
|
14
14
|
extend Forwardable
|
15
15
|
def_delegators :@exporter, :start_export, :start_tracker_segment, :end_tracker_segment, :export_point, :end_export
|
16
16
|
|
17
|
-
# Used to automatically register your
|
17
|
+
# Used to automatically register your tool in Tracksperanto.tools
|
18
18
|
# Normally you wouldn't need to override this
|
19
19
|
def self.inherited(by)
|
20
|
-
Tracksperanto.
|
20
|
+
Tracksperanto.tools.push(by)
|
21
21
|
super
|
22
22
|
end
|
23
23
|
|
24
|
-
# Returns the human name of the action that the
|
24
|
+
# Returns the human name of the action that the tool will perform. The action is
|
25
25
|
# the in infinitive form, like "Remove all the invalid keyframes", "Crop the image" and so on
|
26
26
|
def self.action_description
|
27
|
-
"Base
|
27
|
+
"Base tool class"
|
28
28
|
end
|
29
29
|
|
30
30
|
# Constructor accepts the exporter that will be wrapped, followed by the optional options hash
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# Does the same as the Pad
|
3
|
-
class Tracksperanto::
|
2
|
+
# Does the same as the Pad tool but with absolute pixel values instead of fractionals
|
3
|
+
class Tracksperanto::Tool::Crop < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
parameter :top, :cast => :int, :desc => "Top crop amount in px"
|
6
6
|
parameter :left, :cast => :int, :desc => "Left crop amount in px"
|
@@ -13,7 +13,7 @@ class Tracksperanto::Middleware::Crop < Tracksperanto::Middleware::Base
|
|
13
13
|
|
14
14
|
def start_export(w, h)
|
15
15
|
left_pad, right_pad, top_pad, bottom_pad = (left / w.to_f), (right / w.to_f), (top / h.to_f), (bottom / h.to_f)
|
16
|
-
@pad = Tracksperanto::
|
16
|
+
@pad = Tracksperanto::Tool::Pad.new(@exporter, :left_pad => left_pad, :right_pad => right_pad, :top_pad => top_pad, :bottom_pad => bottom_pad)
|
17
17
|
@pad.start_export(w, h)
|
18
18
|
end
|
19
19
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Flips the comp being exported horizontally
|
3
|
-
class Tracksperanto::
|
3
|
+
class Tracksperanto::Tool::Flip < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Mirrors all the tracker paths horizontally"
|
@@ -8,7 +8,7 @@ class Tracksperanto::Middleware::Flip < Tracksperanto::Middleware::Base
|
|
8
8
|
|
9
9
|
def start_export(w, h)
|
10
10
|
factor = -1
|
11
|
-
@exporter = Tracksperanto::
|
11
|
+
@exporter = Tracksperanto::Tool::Scaler.new(@exporter, :x_factor => factor)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Flips the comp being exported vertically
|
3
|
-
class Tracksperanto::
|
3
|
+
class Tracksperanto::Tool::Flop < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Mirror all the tracker paths vertically"
|
@@ -8,7 +8,7 @@ class Tracksperanto::Middleware::Flop < Tracksperanto::Middleware::Base
|
|
8
8
|
|
9
9
|
def start_export(w, h)
|
10
10
|
factor = -1
|
11
|
-
@exporter = Tracksperanto::
|
11
|
+
@exporter = Tracksperanto::Tool::Scaler.new(@exporter, :y_factor => factor)
|
12
12
|
super
|
13
13
|
end
|
14
14
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# This
|
3
|
-
class Tracksperanto::
|
2
|
+
# This tool marks all trackers as being 100% accurate
|
3
|
+
class Tracksperanto::Tool::Golden < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Reset residual of all the trackers to zero"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# This
|
2
|
+
# This tool removes trackers that contain less than min_length keyframes
|
3
3
|
# from the exported batch
|
4
|
-
class Tracksperanto::
|
4
|
+
class Tracksperanto::Tool::LengthCutoff < Tracksperanto::Tool::Base
|
5
5
|
|
6
6
|
parameter :min_length, :cast => :int, :desc => "The minimum number of keyframes for the item to contain", :default => 100
|
7
7
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
class Tracksperanto::
|
2
|
+
class Tracksperanto::Tool::LensDisto < Tracksperanto::Tool::Base
|
3
3
|
include Tracksperanto::UVCoordinates
|
4
4
|
|
5
5
|
|
@@ -58,7 +58,7 @@ class Tracksperanto::Middleware::LensDisto < Tracksperanto::Middleware::Base
|
|
58
58
|
def with_uv(x, y)
|
59
59
|
vec = Vector2.new(convert_to_uv(x, @width), convert_to_uv(y, @height))
|
60
60
|
yield(vec)
|
61
|
-
[convert_from_uv(
|
61
|
+
[convert_from_uv(vec.x, @width), convert_from_uv(vec.y, @height)]
|
62
62
|
end
|
63
63
|
|
64
64
|
# Radius is equal to aspect at the rightmost extremity
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
-
# This
|
3
|
-
class Tracksperanto::
|
2
|
+
# This tool adds linearly interpolated keyframes BETWEEN the keyframes passing through the exporter
|
3
|
+
class Tracksperanto::Tool::Lerp < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Interpolate missing keyframes of all the trackers"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Prevents you from exporting invalid trackers
|
3
|
-
class Tracksperanto::
|
3
|
+
class Tracksperanto::Tool::Lint < Tracksperanto::Tool::Base
|
4
4
|
|
5
5
|
def self.action_description
|
6
6
|
"Verify all the exported trackers and check for errors"
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
# Sometimes your tracked sequence has been loaded from say frame 73282381, but you want to import into an application
|
3
|
-
# that expects the trackers to start at frame 1. This
|
4
|
-
class Tracksperanto::
|
3
|
+
# that expects the trackers to start at frame 1. This tool autoslips everything so that your trackers start at frame 1.
|
4
|
+
class Tracksperanto::Tool::MoveToFirst < Tracksperanto::Tool::Base
|
5
5
|
|
6
6
|
def self.action_description
|
7
|
-
"Move all the keyframes in time so that the
|
7
|
+
"Move all the keyframes in time so that the track starts at frame 1"
|
8
8
|
end
|
9
9
|
|
10
10
|
def start_export(width, height)
|