Last active
December 24, 2019 10:56
-
-
Save MitchellKehn/3484bad294049b457b100e9a0c588e4e to your computer and use it in GitHub Desktop.
[nuke track exporter] Exporter for nuke 2D tracks into PFTrack-importable format. Exporter not quite working, but has some attribute access stuff that could prove useful #nuke #pftrack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Export a nuke tracker node to an ACII file that can be read by PFTrack | |
""" | |
from math import sqrt | |
HEADER = """\ | |
# "Name" | |
# clipNumber | |
# frameCount | |
# frame, xpos, ypos, similarity | |
""" | |
ATTRS = [ | |
"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" | |
] | |
COL_COUNT = 31 | |
RESIZE = 1520.0 / 4448.0 | |
def attrIndex(attribute, row): | |
""" | |
Get the index of an attribute of the Tracker node | |
@param attribute: the name of the attribute | |
@param row: the row of the table you're accessing | |
""" | |
col = ATTRS.index(attribute) | |
return row * COL_COUNT + col | |
def trackCount(tracker): | |
"""@return the number of trackers on the selected node""" | |
tracks = 0 | |
while node.knob('tracks').isAnimated(31 * tracks + 2): | |
tracks += 1 | |
return tracks | |
def trackRange(tracker, row, first, last): | |
"""@return: frame range where there are keyframes for the given row. None, None if there are none""" | |
tracks = tracker["tracks"] | |
# work out first frame by stepping forwards | |
firstKey = first | |
while firstKey < last: | |
if tracks.isKeyAt(firstKey, attrIndex("track_x", row)) or \ | |
tracks.isKeyAt(firstKey, attrIndex("track_y", row)): | |
break | |
firstKey += 1 | |
else: | |
return None, None | |
# work out last frame by stepping backwards | |
lastKey = last | |
while lastKey > first: | |
if tracks.isKeyAt(lastKey, attrIndex("track_x", row)) or \ | |
tracks.isKeyAt(lastKey, attrIndex("track_y", row)): | |
break | |
lastKey -= 1 | |
return firstKey, lastKey | |
def getTrackNames(tracker4Node): | |
k = tracker4Node['tracks'] | |
s = tracker4Node['tracks'].toScript().split(' \n} \n{ \n ') | |
s.pop(0) | |
ss = str(s)[2:].split('\\n') | |
if ss: | |
ss.pop(-1) | |
if ss: | |
ss.pop(-1) | |
outList = [] | |
for i in ss: | |
outList.append(i.split('"')[1]) | |
return outList | |
def exportTracker(tracker): | |
frange, views = nuke.getFramesAndViews("frame range", "{}-{}".format(nuke.root().firstFrame(), nuke.root().lastFrame())) | |
frange = frange.split("-") | |
firstFrame, lastFrame = int(frange[0]), int(frange[-1]) | |
tracks = tracker["tracks"] | |
fp = nuke.getFilename("Path to ASCII file", "*.txt") | |
with open(fp, "w") as file: | |
file.write(HEADER) | |
for row in range(trackCount(tracker)): | |
firstKey, lastKey = trackRange(tracker, row, firstFrame, lastFrame) | |
if any([firstKey == lastKey, firstKey is None, lastKey is None]): | |
print "no keys in row", row | |
continue # there are no keyframes on this track | |
file.write("\n") | |
# print tracks.getValue(attrIndex("name", row)) # can't get strings from values key_search_t | |
file.write('"NukeTrack{:04d}"\n'.format(row+1)) | |
file.write("1\n") | |
file.write("{}\n".format(lastKey - firstKey + 1)) | |
for frame in range(firstKey, lastKey + 1): | |
xpos = tracks.getValueAt(frame, attrIndex("track_x", row)) | |
ypos = tracks.getValueAt(frame, attrIndex("track_y", row)) | |
simi = 1 - sqrt(tracks.getValueAt(frame, attrIndex("error", row))) | |
file.write("{} {} {} {}\n".format(frame, xpos * RESIZE, ypos * RESIZE, simi)) | |
file.write("\n") | |
with open(fp, "r") as file: | |
print file.read() | |
if __name__ == "__main__": | |
node = nuke.selectedNode() | |
exportTracker(node) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment