123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
-
-
- class MetaDataContainer:
-
- def __init__(self):
- pass
- self.metaHeader = list();
- self.metaData = list();
- self.headerLookup = dict();
- self.syncLookup = dict();
-
- def getValueByName(self, entry, name):
- idx = self.headerLookup[name];
- return entry[idx];
-
- def getIndexByLookupFieldValue(self, value):
-
- try:
- index = self.syncLookup[value];
-
-
-
- except KeyError:
- return None
- return index;
-
- def getMetaDataByLookupFieldValue(self, value):
-
- index = self.syncLookup[value];
- if (index is not None):
- return self.metaData[index];
-
-
- def prepareSyncLookup(self, syncField):
- self.syncLookup = dict()
- self.syncField = syncField;
-
- for index, line in enumerate(self.metaData):
- #line = self.metaData[index];
-
- # prepare syncField speedup
- if self.syncField is not None:
- syncColNum = int(self.headerLookup[self.syncField]);
- #print syncColNum
- self.syncLookup[line[syncColNum]] = index;
-
-
- def loadFromFile(self, file):
- # only csv supported
- if (not file.strip().endswith(".csv")):
- # check first to avoid double onChange callback call
- if (nuke.thisNode().knob(KNOBNAME_METADATAFILE).value() != ""):
- nuke.message("This is not a .csv file!");
- nuke.thisNode().knob(KNOBNAME_METADATAFILE).setValue("")
- return;
-
- f = open(file, "r");
- content = f.readlines();
- for linenumber, line in enumerate(content):
- # line = content[linenumber];
- #print line
- if (linenumber == 0):
- self.metaHeader = line.split("\t");
-
- # store the column number for each name
- for col, data in enumerate(self.metaHeader):
- self.headerLookup[data] = int(col);
-
- continue;
-
- dataColumns = line.split("\t");
-
- self.metaData.append(dataColumns);
-
-
- #dataEntry = dict();
- #for col, data in enumerate(metaHeader):
- # # print col
- # # key = header[col];
- # dataEntry[data] = dataColumns[col];
- #self.metaData.append(dataEntry);
-
-
- #print self.metaData
- import nuke
- import threading
-
-
- nodeTemplate = """
- Group {
- name MetaDataFromFile
- addUserKnob {20 properties l Properties}
- addUserKnob {2 metadatafile l "Metadata File" t "CSV Metadata file"}
- addUserKnob {1 prefix l "Key Prefix" t}
- prefix "ext/"
- addUserKnob {3 offset l "Offset"}
- addUserKnob {26 ""}
- addUserKnob {22 btn_sync l "Synchronize" T "metaDataFromFile.synchronize()"}
- addUserKnob {4 srcfield l "Sync Input Field" M {"No Sync" ""}}
- addUserKnob {4 targetfield l "Sync External Field" M {"No Sync" ""}}
-
-
- metadatafile ""
- knobChanged "metaDataFromFile.userKnobChanged()"
- updateUI "metaDataFromFile.updateUI()"
- }
- Input {
- inputs 0
- name Input1
- xpos 0
- }
- ModifyMetaData {
- metadata {
- }
- name ModifyMetaData
- xpos 0
- ypos 150
- }
- Output {
- name Output1
- xpos 0
- ypos 300
- }
-
- end_group
- """
-
-
-
-
- metaDataLineTemplate = """{set "%s%s" "\[python metaDataFromFile.getMetaField(%s)]"}"""
-
- userKnobTemplate = "addUserKnob {1 %s}"
-
- KNOBNAME_METADATAFILE = "metadatafile"
- KNOBNAME_OFFSET ="offset"
- KNOBNAME_SRCFIELD = "srcfield"
- KNOBNAME_TARGETFIELD = "targetfield"
- KNOBNAME_PREFIX = "prefix"
-
- def loadMetadataFile(node, file):
- meta = MetaDataContainer();
- meta.loadFromFile(file);
-
- metaKeys = list();
-
- prefix = node.knob(KNOBNAME_PREFIX).value()
-
- # set values for each frame
- for num, key in enumerate(meta.metaHeader):
- pass
- metaKeys.append(metaDataLineTemplate % (prefix.strip(), key, int(num)))
-
-
- # get the metadata node
- mmd = nuke.allNodes(group=nuke.thisGroup(), filter="ModifyMetaData")[0]
- mmd["metadata"].fromScript("\n".join(metaKeys));
-
- # fill src/target fields
- if node.input(0) is not None:
- srcFields = node.input(0).metadata().keys()
- node.knob(KNOBNAME_SRCFIELD).setValues(srcFields);
-
- targetFields = meta.metaHeader;
- node.knob(KNOBNAME_TARGETFIELD).setValues(targetFields);
-
- return meta
-
- import linecache
-
- def getMetaField(column, offset = None):
- try:
- if (offset is None):
- offset = int(nuke.thisParent().knob(KNOBNAME_OFFSET).value());
-
- # add 1, the first line is the header
- idx = int(nuke.frame())- offset + 1
-
- file = getMetaFile()
-
- return linecache.getline(file,int(idx)).split("\t")[column].strip()
- except Exception as e:
- return "metadata error: %s" %e
-
-
- def getMetaFile():
- return nuke.thisParent().knob(KNOBNAME_METADATAFILE).value();
-
- def updateUI():
- pass
-
- def userKnobChanged():
- if ((nuke.thisKnob().name() == KNOBNAME_METADATAFILE) or
- (nuke.thisKnob().name() == "inputChange") or
- (nuke.thisKnob().name() == KNOBNAME_PREFIX)) :
- loadMetadataFile(nuke.thisNode(), nuke.thisNode().knob(KNOBNAME_METADATAFILE).value());
-
-
-
-
- def createNode():
- from PySide2 import QtWidgets
- QtWidgets.QApplication.clipboard().setText(nodeTemplate)
- newNode = nuke.nodePaste("%clipboard%")
- #nuke.addKnobChanged(userKnobChanged, node=newNode)
- pass
-
- def synchronize():
-
- meta = loadMetadataFile(nuke.thisNode(),nuke.thisNode().knob(KNOBNAME_METADATAFILE).value() );
-
- srcField = nuke.thisNode().knob(KNOBNAME_SRCFIELD).value();
- targetField = nuke.thisNode().knob(KNOBNAME_TARGETFIELD).value();
-
- meta.prepareSyncLookup(targetField);
-
- # search for a matching value at the current frame
- metaValue = nuke.thisNode().metadata(srcField)
- index = nuke.frame()-meta.getIndexByLookupFieldValue(metaValue) - 1;
-
-
- if (index is None):
- nuke.message("Cannot synchronize: meta data value '%s' (%s) not found in external field '%s'" % (metaValue, srcField, targetField))
- return
-
- nuke.thisNode().knob(KNOBNAME_OFFSET).setValue(index);
-
-
-
-
- if __name__ == "__main__":
- load();
|