flame_channel_parser 4.0.2 → 4.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.travis.yml +6 -1
- data/Gemfile +2 -9
- data/History.txt +4 -0
- data/{README.rdoc → README.md} +33 -14
- data/Rakefile +3 -21
- data/bin/bake_flame_channel +1 -1
- data/bin/flame_channel_inspect +26 -0
- data/flame_channel_parser.gemspec +11 -113
- data/lib/flame_channel_parser.rb +3 -2
- data/lib/flame_channel_parser/version.rb +3 -0
- data/lib/inspector.rb +74 -0
- data/lib/xml_parser.rb +11 -12
- data/test/stabilizer_examples/2014_cornerpin_points.stabilizer +16835 -0
- data/test/test_flame_channel_parser.rb +0 -1
- data/test/test_inspector.rb +39 -0
- data/test/test_inspector_ref_output_stabilizer.txt +76 -0
- data/test/test_inspector_ref_output_timewarp.txt +10 -0
- data/test/test_interpolator.rb +11 -3
- metadata +59 -38
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 63ea2d0b36c71708aed053a7e899fe45a90144f09a76a539bfde0fa75cebdbba
|
4
|
+
data.tar.gz: a28e90fce5c379defb431679b1593f5e9b1a02e1a69ac492b8312066bc1eb86e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7b6359fb57c03a67a048c2679efddff22d1ced66ec00bc93a34fc8a0965a17eb0af749baa3b66423542775e6442d1cf61d509f784c69b8ea46303acbea9cbb95
|
7
|
+
data.tar.gz: caf1e909f3f2f8078218c230e6fc3f882fc2df70fb64b0f8f3e9ce8550314b67b12c401e68c4da541547af01b29e1b56aaef90e260c00f9397474554f42ccfc6
|
data/.gitignore
ADDED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/History.txt
CHANGED
data/{README.rdoc → README.md}
RENAMED
@@ -1,29 +1,48 @@
|
|
1
|
-
|
1
|
+
# flame_channel_parser
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/guerilla-di/flame_channel_parser)
|
4
4
|
|
5
|
-
|
5
|
+
Flame is a compositing powerhouse, and it's animation tools are extremely good for quickly prototyping things in front of clients. However, once you want to pull your
|
6
|
+
animation into other packages it can get troublesome, since only Action nodes currently support any kind of export (and it's FBX, and it's only partial).
|
7
|
+
`flame_channel_parser` alleviates the problem - it can load **any** Flame setup file (an `.action` file, or a `.stabilizer` file, or any file created by one of your
|
8
|
+
Sparks - like Kronos timewarps for examople) and extract arbitrary animation curves as tables of frames and values.
|
6
9
|
|
7
|
-
|
10
|
+
This gem includes a small library for extracting, parsing and baking animation curves made on Discrodesk Floke/Inflinto, also known as flame.
|
8
11
|
Thanks to Marijn Eken, Philippe Soeiro and Andre Gagnon for their support and advice.
|
9
12
|
|
10
|
-
|
13
|
+
## Features:
|
11
14
|
|
12
15
|
* All extrapolation and interpolation methods are supported (yes two keyframes with tangents across 2000 frames will do!)
|
13
16
|
* Expressions on channels won't be evaluated (obviously!)
|
14
17
|
|
15
|
-
|
18
|
+
## Synopsis
|
19
|
+
|
20
|
+
To examing what channels your setup contains, use the flame_channel_inspect_binary
|
21
|
+
|
22
|
+
$flame_channel_inspect /usr/discreet/projects/BZO/timewarp/s02_tw.timewarp
|
16
23
|
|
17
24
|
To just bake a specific channel, use the bake_flame_channel binary.
|
18
25
|
|
19
26
|
$bake_flame_channel --channel Timing/Timing -e 123 /usr/discreet/projects/BZO/timewarp/s02_tw.timewarp > /mnt/3d/curves/shot2_tw.framecurve.txt
|
20
27
|
|
21
|
-
If you just need to
|
28
|
+
If you just need to extract a framecurve file (http://framecurve.org) from a timewarp, use the framecurve_from_flame which autodetects most of the settings by itself and gives you a nice .framecurve.txt file
|
22
29
|
|
23
30
|
$framecurve_from_flame /usr/discreet/projects/BZO/timewarp/s02_tw.timewarp
|
24
|
-
|
31
|
+
|
25
32
|
This will create a framecurve file called s02_tw.timewarp.framecurve.txt next to the setup
|
26
33
|
|
34
|
+
The reverse is true for framecurve_to_flame
|
35
|
+
|
36
|
+
$framecurve_from_flame /usr/discreet/projects/BZO/timewarp/s02_tw.framecurve.txt
|
37
|
+
|
38
|
+
will create setup files for use with both Timewarp modules and the Kronos spark.
|
39
|
+
|
40
|
+
The bonuses are of course in the details - **flame_channel_parser** is a meticulous
|
41
|
+
bitch and will faithfully replicate all the tricky things you can do to your animation curves to give them more _oomph_ - like broken tangents, two keyframes on
|
42
|
+
500 frames with wild oscillations, looping and linear extrapolations, constant interpolations for jumps and so on. In short, this will _interpolate_ your
|
43
|
+
animation channel and extract it frame by frame, so all the animation is intact. **No keyframe baking is necessary** for the Flame operator to do.
|
44
|
+
Of course it supports both varieties of Flame setups - the newer 2012 ones as good as the old 9.0 - 2011 ones.
|
45
|
+
|
27
46
|
To use the library:
|
28
47
|
|
29
48
|
require "flame_channel_parser"
|
@@ -46,19 +65,19 @@ To use the library:
|
|
46
65
|
p interpolator.value_at(frame_in_setup)
|
47
66
|
end
|
48
67
|
|
49
|
-
|
68
|
+
## Requirements
|
50
69
|
|
51
|
-
* Ruby 1.8.
|
70
|
+
* Ruby 1.8.7 and above
|
52
71
|
|
53
|
-
|
72
|
+
## Installation
|
54
73
|
|
55
|
-
|
74
|
+
$gem install flame_channel_parser
|
56
75
|
|
57
|
-
|
76
|
+
## License
|
58
77
|
|
59
78
|
(The MIT License)
|
60
79
|
|
61
|
-
Copyright (c) 2011 Julik Tarkhanov
|
80
|
+
Copyright (c) 2011-2015 Julik Tarkhanov
|
62
81
|
|
63
82
|
Permission is hereby granted, free of charge, to any person obtaining
|
64
83
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -1,23 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'jeweler'
|
5
|
-
require './lib/flame_channel_parser'
|
6
|
-
|
7
|
-
Jeweler::Tasks.new do |gem|
|
8
|
-
gem.version = FlameChannelParser::VERSION
|
9
|
-
gem.name = "flame_channel_parser"
|
10
|
-
gem.summary = "A parser/interpolator for Flame/Smoke animation curves"
|
11
|
-
gem.description = "Reads and interpolates animation channels in IFFS setups"
|
12
|
-
gem.email = "me@julik.nl"
|
13
|
-
gem.homepage = "http://guerilla-di.org/flame-channel-parser/"
|
14
|
-
gem.authors = ["Julik Tarkhanov"]
|
15
|
-
gem.license = 'MIT'
|
16
|
-
end
|
17
|
-
|
18
|
-
Jeweler::RubygemsDotOrgTasks.new
|
19
|
-
|
1
|
+
require "bundler/gem_tasks"
|
20
2
|
require 'rake/testtask'
|
3
|
+
|
21
4
|
desc "Run all tests"
|
22
5
|
Rake::TestTask.new("test") do |t|
|
23
6
|
t.libs << "test"
|
@@ -25,6 +8,5 @@ Rake::TestTask.new("test") do |t|
|
|
25
8
|
t.verbose = true
|
26
9
|
end
|
27
10
|
|
11
|
+
# Automatically update the LICENSE
|
28
12
|
task :default => [ :test ]
|
29
|
-
|
30
|
-
# vim: syntax=ruby
|
data/bin/bake_flame_channel
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
# == Author
|
11
11
|
# Julik <me@julik.nl>
|
12
12
|
|
13
|
-
require File.expand_path(File.dirname(__FILE__)) + '/../lib/flame_channel_parser'
|
13
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../lib/flame_channel_parser'
|
14
14
|
require 'optparse'
|
15
15
|
require 'rubygems'
|
16
16
|
require "update_hints"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# == Synopsis
|
3
|
+
#
|
4
|
+
# Shows a list of animation channels in the given Flame setup file
|
5
|
+
#
|
6
|
+
# == Usage
|
7
|
+
#
|
8
|
+
# flame_channel_inspect /usr/discreet/projects/Luxury/timewarp/shot2_tw.timewarp
|
9
|
+
#
|
10
|
+
# == Author
|
11
|
+
# Julik <me@julik.nl>
|
12
|
+
|
13
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../lib/flame_channel_parser'
|
14
|
+
require 'rubygems'
|
15
|
+
require "update_hints"
|
16
|
+
|
17
|
+
setup_path = ARGV.shift
|
18
|
+
fail "No input file path provided." unless setup_path
|
19
|
+
fail "File does not exist." unless File.exist?(setup_path)
|
20
|
+
|
21
|
+
parser = FlameChannelParser::Parser.new
|
22
|
+
File.open(setup_path, "r") do | f |
|
23
|
+
channels = parser.parse(f)
|
24
|
+
tree = FlameChannelParser::Inspector.new(channels)
|
25
|
+
tree.pretty_print
|
26
|
+
end
|
@@ -1,131 +1,29 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
5
|
-
|
2
|
+
require File.dirname(__FILE__) + '/lib/flame_channel_parser/version'
|
6
3
|
Gem::Specification.new do |s|
|
7
4
|
s.name = "flame_channel_parser"
|
8
|
-
s.version =
|
5
|
+
s.version = FlameChannelParser::VERSION
|
9
6
|
|
10
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
8
|
s.authors = ["Julik Tarkhanov"]
|
12
|
-
s.date = "
|
9
|
+
s.date = Time.now.utc.strftime("%Y-%m-%d")
|
13
10
|
s.description = "Reads and interpolates animation channels in IFFS setups"
|
14
11
|
s.email = "me@julik.nl"
|
15
12
|
s.executables = ["bake_flame_channel", "framecurve_from_flame", "framecurve_to_flame"]
|
16
13
|
s.extra_rdoc_files = [
|
17
|
-
"README.
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".autotest",
|
21
|
-
".travis.yml",
|
22
|
-
"Gemfile",
|
23
|
-
"History.txt",
|
24
|
-
"README.rdoc",
|
25
|
-
"Rakefile",
|
26
|
-
"bin/bake_flame_channel",
|
27
|
-
"bin/framecurve_from_flame",
|
28
|
-
"bin/framecurve_to_flame",
|
29
|
-
"flame_channel_parser.gemspec",
|
30
|
-
"lib/builder.rb",
|
31
|
-
"lib/channel.rb",
|
32
|
-
"lib/extractor.rb",
|
33
|
-
"lib/flame_channel_parser.rb",
|
34
|
-
"lib/framecurve_writers/base.rb",
|
35
|
-
"lib/framecurve_writers/batch_timewarp.rb",
|
36
|
-
"lib/framecurve_writers/kronos.rb",
|
37
|
-
"lib/framecurve_writers/softfx_timewarp.rb",
|
38
|
-
"lib/framecurve_writers/templates/BatchTW.xml",
|
39
|
-
"lib/framecurve_writers/templates/SampleKronos.F_Kronos",
|
40
|
-
"lib/framecurve_writers/templates/TW_Sample.timewarp",
|
41
|
-
"lib/framecurve_writers/templates/key.xml",
|
42
|
-
"lib/interpolator.rb",
|
43
|
-
"lib/key.rb",
|
44
|
-
"lib/parser.rb",
|
45
|
-
"lib/segments.rb",
|
46
|
-
"lib/timewarp_extractor.rb",
|
47
|
-
"lib/xml_parser.rb",
|
48
|
-
"test/channel_with_constants.dat",
|
49
|
-
"test/helper.rb",
|
50
|
-
"test/sample_channel.dat",
|
51
|
-
"test/snaps/BatchTimewar_proper.xml",
|
52
|
-
"test/snaps/BatchTimewarp_ext1.timewarp_node",
|
53
|
-
"test/snaps/Cycle_and_revcycle.action",
|
54
|
-
"test/snaps/FLEM_BrokenTangents.action",
|
55
|
-
"test/snaps/FLEM_advanced_curve.png",
|
56
|
-
"test/snaps/FLEM_advanced_curve_example_FL2012.action",
|
57
|
-
"test/snaps/FLEM_baked_curve.png",
|
58
|
-
"test/snaps/FLEM_curves_example.action",
|
59
|
-
"test/snaps/FLEM_curves_example_migrated_to_2012.action",
|
60
|
-
"test/snaps/FLEM_std_curve.png",
|
61
|
-
"test/snaps/RefT_Steadicam.timewarp",
|
62
|
-
"test/snaps/RefT_Steadicam_Baked.timewarp",
|
63
|
-
"test/snaps/RefT_Steadicam_Extraction.txt",
|
64
|
-
"test/snaps/RefT_Steadicam_Extraction_F19_to_347.txt",
|
65
|
-
"test/snaps/RefT_Steadicam_TwoKFs.timewarp",
|
66
|
-
"test/snaps/RefT_Steadicam_TwoKFs_AnotherSlope.timewarp",
|
67
|
-
"test/snaps/RefT_Steadicam_TwoKFs_HermiteAtBegin.timewarp",
|
68
|
-
"test/snaps/TW.timewarp",
|
69
|
-
"test/snaps/TW_015_010_v03.timewarp",
|
70
|
-
"test/snaps/TW_SingleFrameExtrapolated_from2011.timewarp",
|
71
|
-
"test/snaps/TW_TEST.F_Kronos",
|
72
|
-
"test/snaps/timewarp_where_interp_fails_at_end.timewarp",
|
73
|
-
"test/test_bake_flame_channel_binary.rb",
|
74
|
-
"test/test_base_timewarp_writer.rb",
|
75
|
-
"test/test_batch_timewarp_writer.rb",
|
76
|
-
"test/test_channel.rb",
|
77
|
-
"test/test_cli_framecurve_to_flame.rb",
|
78
|
-
"test/test_cli_timewarp_extractor.rb",
|
79
|
-
"test/test_extractor.rb",
|
80
|
-
"test/test_flame_builder.rb",
|
81
|
-
"test/test_flame_channel_parser.rb",
|
82
|
-
"test/test_interpolator.rb",
|
83
|
-
"test/test_key.rb",
|
84
|
-
"test/test_kronos_timewarp_writer.rb",
|
85
|
-
"test/test_segments.rb",
|
86
|
-
"test/test_softfx_timewarp_writer.rb",
|
87
|
-
"test/test_timewarp_extractor.rb",
|
88
|
-
"test/test_xml_setup.rb",
|
89
|
-
"test/timewarp_examples/TW_015_010_v01_Baked.timewarp",
|
90
|
-
"test/timewarp_examples/TW_016_010_v01.timewarp",
|
91
|
-
"test/timewarp_examples/TW_016_010_v01_Baked.timewarp",
|
92
|
-
"test/timewarp_examples/TW_16_010_v01.output.txt",
|
93
|
-
"test/timewarp_examples/TW_TEST.F_Kronos",
|
94
|
-
"test/timewarp_examples/output.txt",
|
95
|
-
"test/timewarp_examples/simple.framecurve.txt",
|
96
|
-
"test/timewarp_examples/tw_batch_out.framecurve.txt",
|
97
|
-
"test/timewarp_export_samples/BatchTW.timewarp_node",
|
98
|
-
"test/timewarp_export_samples/Kronos.F_Kronos",
|
99
|
-
"test/timewarp_export_samples/SoftFX.timewarp"
|
14
|
+
"README.md"
|
100
15
|
]
|
16
|
+
s.files = `git ls-files -z`.split("\x0")
|
101
17
|
s.homepage = "http://guerilla-di.org/flame-channel-parser/"
|
102
18
|
s.licenses = ["MIT"]
|
103
19
|
s.require_paths = ["lib"]
|
104
20
|
s.rubygems_version = "1.8.11"
|
105
21
|
s.summary = "A parser/interpolator for Flame/Smoke animation curves"
|
106
22
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
114
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
115
|
-
s.add_development_dependency(%q<cli_test>, ["~> 1.0"])
|
116
|
-
else
|
117
|
-
s.add_dependency(%q<update_hints>, ["~> 1.0"])
|
118
|
-
s.add_dependency(%q<framecurve>, ["~> 1.0.1"])
|
119
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
120
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
121
|
-
s.add_dependency(%q<cli_test>, ["~> 1.0"])
|
122
|
-
end
|
123
|
-
else
|
124
|
-
s.add_dependency(%q<update_hints>, ["~> 1.0"])
|
125
|
-
s.add_dependency(%q<framecurve>, ["~> 1.0.1"])
|
126
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
127
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
128
|
-
s.add_dependency(%q<cli_test>, ["~> 1.0"])
|
129
|
-
end
|
23
|
+
s.specification_version = 3
|
24
|
+
s.add_runtime_dependency("update_hints", ["~> 1.0"])
|
25
|
+
s.add_runtime_dependency("framecurve", ["~> 2"])
|
26
|
+
s.add_development_dependency("rake", [">= 0"])
|
27
|
+
s.add_development_dependency("cli_test", ["~> 1.0"])
|
28
|
+
s.add_development_dependency("test-unit")
|
130
29
|
end
|
131
|
-
|
data/lib/flame_channel_parser.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/flame_channel_parser/version'
|
2
|
+
|
1
3
|
module FlameChannelParser
|
2
|
-
VERSION = '4.0.2'
|
3
4
|
|
4
5
|
module FramecurveWriters; end
|
5
6
|
|
@@ -37,7 +38,7 @@ module FlameChannelParser
|
|
37
38
|
end
|
38
39
|
|
39
40
|
%w(
|
40
|
-
key channel parser segments interpolator extractor timewarp_extractor builder xml_parser
|
41
|
+
key channel parser segments interpolator extractor timewarp_extractor builder xml_parser inspector
|
41
42
|
).each {|f| require File.expand_path(File.dirname(__FILE__) + "/" + f ) }
|
42
43
|
|
43
44
|
%w(
|
data/lib/inspector.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Prints out a viewable tree of channel metadata. Useful when you need to inspect comparable setups
|
2
|
+
# for small differentces in channel ordering and animation.
|
3
|
+
class FlameChannelParser::Inspector
|
4
|
+
|
5
|
+
def initialize(channels_arr)
|
6
|
+
@branches = OH.new
|
7
|
+
channels_arr.each {|c| cluster(c) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def pretty_print(output = $stdout)
|
11
|
+
@out = output
|
12
|
+
print_branch(@branches, initial_indent = 0)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
class OH < Hash # It sucks to be Ruby 1.8-compatible sometimes.
|
18
|
+
def initialize
|
19
|
+
super
|
20
|
+
@keys_in_order = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def []=(k, v)
|
24
|
+
@keys_in_order.delete(k)
|
25
|
+
@keys_in_order << k
|
26
|
+
super(k, v)
|
27
|
+
end
|
28
|
+
|
29
|
+
def each_pair
|
30
|
+
@keys_in_order.each {|k| yield(k, self[k]) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def puts(string)
|
35
|
+
@out.puts(string)
|
36
|
+
end
|
37
|
+
|
38
|
+
def print_branch(branch, indent)
|
39
|
+
branch.each_pair do | k, v|
|
40
|
+
if v.is_a?(Hash)
|
41
|
+
puts((" " * indent) + k)
|
42
|
+
print_branch(v, indent + 1)
|
43
|
+
else
|
44
|
+
puts((" " * indent) + k + " - " + channel_metadata(v))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def channel_metadata(channel)
|
50
|
+
if channel.length.zero?
|
51
|
+
"no animations, value %s" % [channel.base_value]
|
52
|
+
elsif channel.length > 1
|
53
|
+
first_key = channel[0].frame
|
54
|
+
last_key = channel[-1].frame
|
55
|
+
"animated, %d keys, first at %d last at %d" % [channel.length, first_key, last_key]
|
56
|
+
else
|
57
|
+
first_key = channel[0].frame
|
58
|
+
"animated, 1 key at %d, value %s" % [first_key, channel[0].value]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def cluster(channel)
|
63
|
+
path_parts = channel.name.split('/')
|
64
|
+
leaf_name = path_parts.pop
|
65
|
+
|
66
|
+
current = @branches
|
67
|
+
path_parts.each do | path_part |
|
68
|
+
current[path_part] ||= OH.new
|
69
|
+
current = current[path_part]
|
70
|
+
end
|
71
|
+
current[leaf_name] = channel
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|