Ei kuvausta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

metaDataFromFile.py 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. class MetaDataContainer:
  2. def __init__(self):
  3. pass
  4. self.metaHeader = list();
  5. self.metaData = list();
  6. self.headerLookup = dict();
  7. self.syncLookup = dict();
  8. def getValueByName(self, entry, name):
  9. idx = self.headerLookup[name];
  10. return entry[idx];
  11. def getIndexByLookupFieldValue(self, value):
  12. try:
  13. index = self.syncLookup[value];
  14. except KeyError:
  15. return None
  16. return index;
  17. def getMetaDataByLookupFieldValue(self, value):
  18. index = self.syncLookup[value];
  19. if (index is not None):
  20. return self.metaData[index];
  21. def prepareSyncLookup(self, syncField):
  22. self.syncLookup = dict()
  23. self.syncField = syncField;
  24. for index, line in enumerate(self.metaData):
  25. #line = self.metaData[index];
  26. # prepare syncField speedup
  27. if self.syncField is not None:
  28. syncColNum = int(self.headerLookup[self.syncField]);
  29. #print syncColNum
  30. self.syncLookup[line[syncColNum]] = index;
  31. def loadFromFile(self, file):
  32. # only csv supported
  33. if (not file.strip().endswith(".csv")):
  34. # check first to avoid double onChange callback call
  35. if (nuke.thisNode().knob(KNOBNAME_METADATAFILE).value() != ""):
  36. nuke.message("This is not a .csv file!");
  37. nuke.thisNode().knob(KNOBNAME_METADATAFILE).setValue("")
  38. return;
  39. f = open(file, "r");
  40. content = f.readlines();
  41. for linenumber, line in enumerate(content):
  42. # line = content[linenumber];
  43. #print line
  44. if (linenumber == 0):
  45. self.metaHeader = line.split("\t");
  46. # store the column number for each name
  47. for col, data in enumerate(self.metaHeader):
  48. self.headerLookup[data] = int(col);
  49. continue;
  50. dataColumns = line.split("\t");
  51. self.metaData.append(dataColumns);
  52. #dataEntry = dict();
  53. #for col, data in enumerate(metaHeader):
  54. # # print col
  55. # # key = header[col];
  56. # dataEntry[data] = dataColumns[col];
  57. #self.metaData.append(dataEntry);
  58. #print self.metaData
  59. import nuke
  60. import threading
  61. nodeTemplate = """
  62. Group {
  63. name MetaDataFromFile
  64. addUserKnob {20 properties l Properties}
  65. addUserKnob {2 metadatafile l "Metadata File" t "CSV Metadata file"}
  66. addUserKnob {1 prefix l "Key Prefix" t}
  67. prefix "ext/"
  68. addUserKnob {3 offset l "Offset"}
  69. addUserKnob {26 ""}
  70. addUserKnob {22 btn_sync l "Synchronize" T "metaDataFromFile.synchronize()"}
  71. addUserKnob {4 srcfield l "Sync Input Field" M {"No Sync" ""}}
  72. addUserKnob {4 targetfield l "Sync External Field" M {"No Sync" ""}}
  73. metadatafile ""
  74. knobChanged "metaDataFromFile.userKnobChanged()"
  75. updateUI "metaDataFromFile.updateUI()"
  76. }
  77. Input {
  78. inputs 0
  79. name Input1
  80. xpos 0
  81. }
  82. ModifyMetaData {
  83. metadata {
  84. }
  85. name ModifyMetaData
  86. xpos 0
  87. ypos 150
  88. }
  89. Output {
  90. name Output1
  91. xpos 0
  92. ypos 300
  93. }
  94. end_group
  95. """
  96. metaDataLineTemplate = """{set "%s%s" "\[python metaDataFromFile.getMetaField(%s)]"}"""
  97. userKnobTemplate = "addUserKnob {1 %s}"
  98. KNOBNAME_METADATAFILE = "metadatafile"
  99. KNOBNAME_OFFSET ="offset"
  100. KNOBNAME_SRCFIELD = "srcfield"
  101. KNOBNAME_TARGETFIELD = "targetfield"
  102. KNOBNAME_PREFIX = "prefix"
  103. def loadMetadataFile(node, file):
  104. meta = MetaDataContainer();
  105. meta.loadFromFile(file);
  106. metaKeys = list();
  107. prefix = node.knob(KNOBNAME_PREFIX).value()
  108. # set values for each frame
  109. for num, key in enumerate(meta.metaHeader):
  110. pass
  111. metaKeys.append(metaDataLineTemplate % (prefix.strip(), key, int(num)))
  112. # get the metadata node
  113. mmd = nuke.allNodes(group=nuke.thisGroup(), filter="ModifyMetaData")[0]
  114. mmd["metadata"].fromScript("\n".join(metaKeys));
  115. # fill src/target fields
  116. if node.input(0) is not None:
  117. srcFields = node.input(0).metadata().keys()
  118. node.knob(KNOBNAME_SRCFIELD).setValues(srcFields);
  119. targetFields = meta.metaHeader;
  120. node.knob(KNOBNAME_TARGETFIELD).setValues(targetFields);
  121. return meta
  122. import linecache
  123. def getMetaField(column, offset = None):
  124. try:
  125. if (offset is None):
  126. offset = int(nuke.thisParent().knob(KNOBNAME_OFFSET).value());
  127. # add 1, the first line is the header
  128. idx = int(nuke.frame())- offset + 1
  129. file = getMetaFile()
  130. return linecache.getline(file,int(idx)).split("\t")[column].strip()
  131. except Exception as e:
  132. return "metadata error: %s" %e
  133. def getMetaFile():
  134. return nuke.thisParent().knob(KNOBNAME_METADATAFILE).value();
  135. def updateUI():
  136. pass
  137. def userKnobChanged():
  138. if ((nuke.thisKnob().name() == KNOBNAME_METADATAFILE) or
  139. (nuke.thisKnob().name() == "inputChange") or
  140. (nuke.thisKnob().name() == KNOBNAME_PREFIX)) :
  141. loadMetadataFile(nuke.thisNode(), nuke.thisNode().knob(KNOBNAME_METADATAFILE).value());
  142. def createNode():
  143. from PySide2 import QtWidgets
  144. QtWidgets.QApplication.clipboard().setText(nodeTemplate)
  145. newNode = nuke.nodePaste("%clipboard%")
  146. #nuke.addKnobChanged(userKnobChanged, node=newNode)
  147. pass
  148. def synchronize():
  149. meta = loadMetadataFile(nuke.thisNode(),nuke.thisNode().knob(KNOBNAME_METADATAFILE).value() );
  150. srcField = nuke.thisNode().knob(KNOBNAME_SRCFIELD).value();
  151. targetField = nuke.thisNode().knob(KNOBNAME_TARGETFIELD).value();
  152. meta.prepareSyncLookup(targetField);
  153. # search for a matching value at the current frame
  154. metaValue = nuke.thisNode().metadata(srcField)
  155. index = nuke.frame()-meta.getIndexByLookupFieldValue(metaValue) - 1;
  156. if (index is None):
  157. nuke.message("Cannot synchronize: meta data value '%s' (%s) not found in external field '%s'" % (metaValue, srcField, targetField))
  158. return
  159. nuke.thisNode().knob(KNOBNAME_OFFSET).setValue(index);
  160. if __name__ == "__main__":
  161. load();