-- replaces the content of a node graph with the content of an ORBX file -- -- @description Reload ORBX -- @author Roeland Schoukens -- @version 0.1 -- @script-id ReloadORBX -- This refreshes a node graph from a file. An easy way of doing so -- is to remove any non-linker items, import the ORBX file into the -- graph, connect any matching linkers, and ungroup the imported graph. local byNameAndTypeMT = { -- the __index() meta function will automagically create -- an empty table if we ask for a key which is not yet set. __index = function(table, key) local t = {} table[key] = t return t end } local function mapNamesAndTypes(t) local byNameAndType = {} setmetatable(byNameAndType, byNameAndTypeMT) for _, n in ipairs(t) do local tt = byNameAndType[n.type] or {} byNameAndType[n.type][n.name] = n; end return byNameAndType end -- this function does one graph: the existing graph contents will -- be replaced by the contents of newGraph, while connectivity -- to linkers will be retained local function replaceContents(existing, newGraph) -- destroy all non-linker items local existingItems = existing:getOwnedItems() for _, n in ipairs(existingItems) do if not n.isLinker then n:destroy() end end -- copy our new graph into the existing graph newGraph = existing:copyFrom({newGraph}, {newGraph})[1] -- connect any matching linkers local existingInputs = existing:getInputNodes() existingInputs = mapNamesAndTypes(existingInputs) for i, n in ipairs(newGraph:getInputNodes()) do local el = existingInputs[n.type][n.name] if el and el.type == n.type then n:connectToIx(1, el) end end local existingOutputs = existing:getOutputNodes() existingOutputs = mapNamesAndTypes(existingOutputs) for i, n in ipairs(newGraph:getOutputNodes()) do local el = existingOutputs[n.type][n.name] if el and el.type == n.type then el:connectToIx(1, n) end end -- ungroup the original graph. newGraph.name = existing.name existing:ungroup() end -- get selection local sel = octane.project.getSelection() local existing = sel[1] if not existing or existing.graphType ~= octane.GT_STANDARD then error("Please select at least one graph first") end -- File chooser octane.storage.app = octane.storage.app or {} local file = octane.gui.showDialog{ path=octane.storage.app.lastdir, type=octane.gui.dialogType.FILE_DIALOG, save=false, title="select ORBX file", wildcards="*.orbx;*.ocs;*.ocm"} if file.result == "" then return end file = file.result octane.storage.app.lastdir = octane.file.getParentDirectory(file) -- import local rootgraph = octane.nodegraph.createRootGraph(existing.name) octane.nodegraph.importFromFile(rootgraph, file) local rootOwned = rootgraph:getOwnedItems() if #rootOwned ~= 1 then error("Imported ORBX contains multiple items") end -- replace all selected nodes local counter = 0 for _, g in ipairs(sel) do if g.graphType == octane.GT_STANDARD then replaceContents(g, rootOwned[1]) counter = counter + 1 end end print(counter.." graphs refreshed")