lib/import/nuke_script.rb in tracksperanto-3.1.0 vs lib/import/nuke_script.rb in tracksperanto-3.2.0

- old
+ new

@@ -1,8 +1,9 @@ # -*- encoding : utf-8 -*- require 'delegate' require File.expand_path(File.dirname(__FILE__)) + "/nuke_grammar/utils" +require 'tickly' class Tracksperanto::Import::NukeScript < Tracksperanto::Import::Base def self.human_name "Nuke .nk script file with Tracker, Reconcile3D and PlanarTracker nodes" @@ -11,106 +12,123 @@ def self.distinct_file_ext ".nk" end def self.known_snags - 'The only supported nodes that we can extract tracks from are Reconcile3D, PlanarTracker and Tracker' + 'The only supported nodes that we can extract tracks from are Reconcile3D, PlanarTracker and Tracker (supported Nuke versions are 5, 6 and 7)' end def each - io = Tracksperanto::ExtIO.new(@io) - while line = io.gets_and_strip - if line =~ TRACKER_3_PATTERN - scan_tracker_node(io).each(&Proc.new) - elsif line =~ RECONCILE_PATTERN - scan_reconcile_node(io).each(&Proc.new) - elsif line =~ PLANAR_PATTERN - scan_planar_tracker_node(io).each(&Proc.new) + script_tree = Tickly::Parser.new.parse(@io) + evaluator = Tickly::Evaluator.new + evaluator.add_node_handler_class(Tracker3) + evaluator.add_node_handler_class(Reconcile3D) + evaluator.add_node_handler_class(PlanarTracker1_0) + evaluator.add_node_handler_class(Tracker4) + + script_tree.each do | node | + result = evaluator.evaluate(node) + if result + result.trackers.each do | t | + report_progress("Scavenging tracker #{t.name}") + yield t + end end end end private - - TRACKER_3_PATTERN = /^Tracker3 \{/ - RECONCILE_PATTERN = /^Reconcile3D \{/ - PLANAR_PATTERN = /^PlanarTracker1_0 \{/ - OUTPUT_PATTERN = /^output \{/ - TRACK_PATTERN = /^track(\d) \{/ - NODENAME = /^name ([^\n]+)/ - PLANAR_CORNERS = %w( outputBottomLeft outputBottomRight outputTopLeft outputTopRight) - - # Scans a Reconcile3D node and returs it's output - def scan_reconcile_node(io) - t = Tracksperanto::Tracker.new - while line = io.gets_and_strip - if line =~ OUTPUT_PATTERN - t = extract_tracker(line) - elsif line =~ NODENAME - t.name = "Reconcile_#{$1}" - report_progress("Scavenging Reconcile3D node #{t.name}") - return [t] # Klunky - end + + class Tracker3 + include Tracksperanto::ZipTuples + attr_reader :trackers + + def initialize(options) + @trackers = [] + point_channels.each do | point_name | + next unless options[point_name] + point_channel = options[point_name] + + curves = extract_curves_from_channel(point_channel) + + # We must always have 2 anim curves + next unless curves.length == 2 + + full_name = [options["name"], point_name].join('_') + tracker = package_tracker(full_name, curves[0], curves[1]) + + @trackers << tracker end end - # Scans a PlanarTracker node and recovers corner pin - def scan_planar_tracker_node(io) - trackers, node_name = [], nil - while line = io.gets_and_strip - PLANAR_CORNERS.each do | corner_name | - if line =~ /#{corner_name}/ - t = Tracksperanto::Tracker.new - t = extract_tracker(line) - t.name = corner_name - trackers.push(t.dup) - elsif line =~ NODENAME - node_name = $1 - end + def package_tracker(full_name, xcurve, ycurve) + frame_x_and_y = zip_curve_tuples(xcurve, ycurve) + Tracksperanto::Tracker.new(:name => full_name) do | t | + frame_x_and_y.each do | (f, x, y) | + t.keyframe!(:frame => (f -1), :abs_x => x, :abs_y => y) end - - if node_name && trackers.length == 4 - trackers.each{|t| t.name = "%s_%s" % [node_name, t.name] } - return trackers - end end - - # Fail - return [] end - # Scans a tracker node and return all tracks within that node (no more than 4) - def scan_tracker_node(io) - tracks_in_tracker = [] - while line = io.gets_and_strip - if line =~ TRACK_PATTERN - t = extract_tracker(line) - tracks_in_tracker.push(t) if t - elsif line =~ NODENAME - tracks_in_tracker.each_with_index do | t, i | - t.name = "#{$1}_track#{i+1}" - report_progress("Scavenging Tracker3 node #{t.name}") - end - return tracks_in_tracker + def extract_curves_from_channel(point_channel) + u = Tracksperanto::NukeGrammarUtils.new + point_channel.to_a.map do | curve_argument | + if curve_argument[0] == "curve" + u.parse_curve(curve_argument.to_a) + else + nil end - end - raise "Tracker node went all the way to end of stream" + end.compact end - def scan_track(line_with_curve) - x_curve, y_curve = line_with_curve.split(/\}/).map do | one_curve| - Tracksperanto::NukeGrammarUtils.new.parse_curve(one_curve) - end - return nil unless (x_curve && y_curve) - zip_curve_tuples(x_curve, y_curve) + def point_channels + %w( track1 track2 track3 track4 ) end - def extract_tracker(line) - tuples = scan_track(line) - return nil unless (tuples && tuples.any?) - Tracksperanto::Tracker.new do | t | - tuples.each do | (f, x, y) | - t.keyframe!(:frame => (f -1), :abs_x => x, :abs_y => y) - end + end + + class Reconcile3D < Tracker3 + def point_channels + %w( output) + end + end + + class PlanarTracker1_0 < Tracker3 + def point_channels + %w( outputBottomLeft outputBottomRight outputTopLeft outputTopRight) + end + end + + class Tracker4 < Tracker3 + + def initialize(options) + + @name = options["name"] + @trackers = [] + tracks = options["tracks"] + preamble = tracks[0] + headers = tracks[1] + values = tracks[2] + + table_headers = headers[0].map{|header| header[0][-1]} + #puts table_headers.inspect + # When this was written, this was the order of the columns in the table: + # le("e", "name", "track_x", "track_y", "offset_x", "offset_y", "T", "R", "S", "error", + # "error_min", "error_max", "pattern_x", "pattern_y", "pattern_r", "pattern_t", "search_x", + # "search_y", "search_r", "search_t", "key_track", "key_search_x", "key_search_y", "key_search_r", + # "key_search_t", "key_track_x", "key_track_y", "key_track_r", "key_track_t", "key_centre_offset_x", "key_centre_offset_y") + tracker_rows = values[0] + + u = Tracksperanto::NukeGrammarUtils.new + + tracker_rows.each do | row | + row_content = row[0][0] + # For offsets see above + point_name, x_curve, y_curve = row_content[1], u.parse_curve(row_content[2].to_a), u.parse_curve(row_content[3].to_a) + + full_name = [options["name"], point_name].join('_') + tracker = package_tracker(full_name, x_curve, y_curve) + @trackers << tracker end end + end end