flame_channel_parser 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/README.rdoc +7 -1
- data/bin/bake_flame_channel +5 -5
- data/lib/extractor.rb +13 -6
- data/lib/flame_channel_parser.rb +1 -1
- data/lib/segments.rb +8 -5
- data/test/test_extractor.rb +24 -2
- metadata +4 -4
data/History.txt
CHANGED
data/README.rdoc
CHANGED
@@ -14,9 +14,15 @@ Thanks to Marijn Eken, Philippe Soeiro and Andre Gagnon for their support and ad
|
|
14
14
|
|
15
15
|
== SYNOPSIS:
|
16
16
|
|
17
|
-
|
17
|
+
To just bake a specific channel, use the bake_flame_channel binary.
|
18
|
+
|
19
|
+
$ bake_flame_channel --channel \"Timing/Timing\" -e 123 /usr/discreet/projects/BZO/timewarp/s02_tw.timewarp > /mnt/3d/curves/shot2_tw.framecurve.txt
|
20
|
+
|
21
|
+
To use the library:
|
18
22
|
|
19
23
|
require "flame_channel_parser"
|
24
|
+
|
25
|
+
# Parse the setup into channels
|
20
26
|
channels = File.open("TW_Setup.timewarp") do | f |
|
21
27
|
FlameChannelParser.parse(f)
|
22
28
|
end
|
data/bin/bake_flame_channel
CHANGED
@@ -6,16 +6,16 @@ options = {}
|
|
6
6
|
|
7
7
|
op = OptionParser.new
|
8
8
|
op.banner = "Usage: bake_flame_channel --channel \"Timing/Timing\" -e 123 /usr/discreet/projects/Luxury/timewarp/shot2_tw.timewarp > /mnt/3d/curves/shot2_tw.framecurve.txt\n" +
|
9
|
-
"The output file can be used as Time+Value ASCII input for Nuke
|
9
|
+
"The output file can be used as Time+Value ASCII input for Nuke " +
|
10
10
|
"or parsed with any simple script"
|
11
11
|
op.on(" -c", "--channel CHANNEL_NAME", String,
|
12
|
-
"Select the channel to bake (for example in Timewarp setups the useful one is Timing/Timing)"
|
12
|
+
"Select the channel to bake (for example in Timewarp setups the useful one is Timing/Timing)."
|
13
13
|
) {|chan| options[:channel] = chan }
|
14
14
|
op.on(" -s", "--startframe FRAME", Integer,
|
15
|
-
"Bake the curve from this specific frame onwards (defaults to the first keyframe in the setup"
|
15
|
+
"Bake the curve from this specific frame onwards (defaults to the first keyframe in the setup)"
|
16
16
|
) {|from| options[:start_frame] = from }
|
17
17
|
op.on(" -e", "--endframe FRAME", Integer,
|
18
|
-
"Bake the curve upto this specific frame (defaults to the last keyframe in the setup"
|
18
|
+
"Bake the curve upto this specific frame (defaults to the last keyframe in the setup)"
|
19
19
|
) {|upto| options[:end_frame] = upto }
|
20
20
|
op.on(" -f", "--to-file FILENAME", String,
|
21
21
|
"Write the curve to a file at this path instead of printing it to STDOUT"
|
@@ -23,7 +23,7 @@ op.on(" -f", "--to-file FILENAME", String,
|
|
23
23
|
|
24
24
|
op.parse!
|
25
25
|
setup_path = ARGV.shift
|
26
|
-
raise "No input file path provided" unless setup_path
|
26
|
+
raise "No input file path provided. Please see bake_flame_channel --help for usage information" unless setup_path
|
27
27
|
|
28
28
|
FlameChannelParser::Extractor.new.extract(setup_path, options)
|
29
29
|
options[:destination].close if options[:destination].respond_to?(:close)
|
data/lib/extractor.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
# Extracts and bakes a specific animation channel
|
2
2
|
class FlameChannelParser::Extractor
|
3
3
|
|
4
|
-
|
4
|
+
DEFAULT_CHANNEL_TO_EXTRACT = "Timing/Timing"
|
5
|
+
DEFAULTS = {:destination => $stdout, :start_frame => nil, :end_frame => nil, :channel => DEFAULT_CHANNEL_TO_EXTRACT }
|
5
6
|
|
6
7
|
# Raised when a channel is not found in the setup file
|
7
|
-
class ChannelNotFoundError < RuntimeError
|
8
|
-
|
8
|
+
class ChannelNotFoundError < RuntimeError; end
|
9
|
+
|
10
|
+
# Raised when you try to autodetect the length of a channel that has no keyframes
|
11
|
+
class NoKeyframesError < RuntimeError; end
|
9
12
|
|
10
13
|
# Pass the path to Flame setup here and you will get the timewarp curve on STDOUT
|
11
14
|
def self.extract(path, options = {})
|
12
15
|
options = DEFAULTS.merge(options)
|
13
16
|
File.open(path) do | f |
|
14
17
|
channels = FlameChannelParser.parse(f)
|
15
|
-
selected_channel = channels.find{|c| options[:channel] == c.
|
18
|
+
selected_channel = channels.find{|c| options[:channel] == c.path }
|
16
19
|
unless selected_channel
|
17
|
-
message = "Channel
|
20
|
+
message = "Channel #{options[:channel]} not found in this setup (set the channel with the --channel option). Found other channels though:"
|
18
21
|
message << "\n"
|
19
|
-
message += channels.map{|c| c.
|
22
|
+
message += channels.map{|c| "\t%s\n" % c.path }.join
|
20
23
|
raise ChannelNotFoundError, message
|
21
24
|
end
|
22
25
|
|
@@ -31,6 +34,10 @@ class FlameChannelParser::Extractor
|
|
31
34
|
|
32
35
|
from_frame = start_frame || interpolator.first_defined_frame
|
33
36
|
to_frame = end_frame || interpolator.last_defined_frame
|
37
|
+
unless (from_frame && to_frame)
|
38
|
+
raise NoKeyframesError, "This channel probably has no animation so there is no way to automatically tell how many keyframes it has. " +
|
39
|
+
"Please set the start and end frame explicitly."
|
40
|
+
end
|
34
41
|
|
35
42
|
(from_frame..to_frame).each do | frame |
|
36
43
|
to_io.puts("%d\t%.5f" % [frame, interpolator.sample_at(frame)])
|
data/lib/flame_channel_parser.rb
CHANGED
data/lib/segments.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "matrix"
|
2
2
|
|
3
|
-
|
3
|
+
|
4
|
+
# :nodoc:
|
5
|
+
module FlameChannelParser::Segments
|
4
6
|
|
5
7
|
# This segment just stays on the value of it's keyframe
|
6
8
|
class ConstantSegment
|
@@ -92,14 +94,14 @@ module FlameChannelParser::Segments
|
|
92
94
|
|
93
95
|
end
|
94
96
|
|
95
|
-
Point = Struct.new(:x, :y, :tanx, :tany)
|
96
|
-
|
97
97
|
class BezierSegment < LinearSegment
|
98
|
+
Pt = Struct.new(:x, :y, :tanx, :tany)
|
99
|
+
|
98
100
|
def initialize(x1, x2, y1, y2, t1x, t1y, t2x, t2y)
|
99
101
|
@start_frame, @end_frame = x1, x2
|
100
102
|
|
101
|
-
@a =
|
102
|
-
@b =
|
103
|
+
@a = Pt.new(x1, y1, t1x, t1y)
|
104
|
+
@b = Pt.new(x2, y2, t2x, t2y)
|
103
105
|
end
|
104
106
|
|
105
107
|
def value_at(frame)
|
@@ -254,3 +256,4 @@ module FlameChannelParser::Segments
|
|
254
256
|
end
|
255
257
|
end
|
256
258
|
|
259
|
+
# :nodoc:
|
data/test/test_extractor.rb
CHANGED
@@ -4,23 +4,45 @@ require "stringio"
|
|
4
4
|
require File.dirname(__FILE__) + "/../lib/flame_channel_parser"
|
5
5
|
|
6
6
|
class TestExtractor < Test::Unit::TestCase
|
7
|
-
def
|
7
|
+
def test_basic_operation
|
8
8
|
io = StringIO.new
|
9
9
|
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/RefT_Steadicam.timewarp", :destination => io)
|
10
10
|
assert_equal File.read(File.dirname(__FILE__) + "/snaps/RefT_Steadicam_Extraction.txt"), io.string
|
11
11
|
end
|
12
12
|
|
13
|
+
def test_channel_selection_by_path_raises_with_not_animated_channel_and_no_start_and_end
|
14
|
+
io = StringIO.new
|
15
|
+
ops = {:destination => io, :channel => "axis1/position/z"}
|
16
|
+
assert_raise(FlameChannelParser::Extractor::NoKeyframesError) do
|
17
|
+
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/FLEM_curves_example_migrated_to_2012.action", ops)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_channel_selection_by_path_outputs_properly
|
22
|
+
io = StringIO.new
|
23
|
+
ops = {:destination => io, :channel => "axis1/position/y"}
|
24
|
+
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/FLEM_curves_example_migrated_to_2012.action", ops)
|
25
|
+
assert_match /12 -101.80433/, io.string
|
26
|
+
end
|
27
|
+
|
28
|
+
|
13
29
|
def test_frame_overrides
|
14
30
|
io = StringIO.new
|
15
31
|
o = {:destination => io, :start_frame => 19, :end_frame => 347 }
|
16
32
|
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/RefT_Steadicam.timewarp", o)
|
17
|
-
|
18
33
|
assert_equal File.read(File.dirname(__FILE__) + "/snaps/RefT_Steadicam_Extraction_F19_to_347.txt"), io.string
|
19
34
|
end
|
20
35
|
|
36
|
+
def test_constant_channels_need_domain_of_definition_on_time
|
37
|
+
assert_raise(FlameChannelParser::Extractor::NoKeyframesError) do
|
38
|
+
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/RefT_Steadicam.timewarp", :channel => "Mix/Mix")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
21
42
|
def test_raises_on_Missing_channel
|
22
43
|
assert_raise(FlameChannelParser::Extractor::ChannelNotFoundError) do
|
23
44
|
FlameChannelParser::Extractor.extract(File.dirname(__FILE__) + "/snaps/RefT_Steadicam.timewarp", :channel => "foo/bar")
|
24
45
|
end
|
25
46
|
end
|
47
|
+
|
26
48
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flame_channel_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 1.3.
|
9
|
+
- 1
|
10
|
+
version: 1.3.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Julik Tarkhanov
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-06-03 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|