grimm wrote:Hi Thomas,
Still have some problems with the code fix:
Did you mean:
- Code: Select all
local copyCam = getInputNode(copyRt, octane.P_CAMERA)
instead of:
- Code: Select all
local copyCam = copyRt:getInputNode(octane.P_CAMERA)
Even with changing that line of code I'm still getting an error:
"attempt to call method 'getConnectedNode' (a nil value)"
on this line:
- Code: Select all
local connected = node:getConnectedNode(pinId)
Now my test scene is real simple, all I have is a mesh node with two render targets connected to it. To test this I grouped both of the target nodes, would this work?
Thanks,
Jason
Hmm, both versions should work but I think I should read up on the Lua docs tomorrow. At least the one without the colon should work. I would've sworn that it worked yesterday. Maybe my new year hangover?
When grouping the render target nodes, you should select the render target node inside the group (not the group itself because this is a graph). However with the code as is it wouldn't work. The problem is that we create a copy of the root scene graph, but the render target nested in the grouped graph isn't returned in
getOwnedItems()
. So the script would error out before it finds it.You can make it work by only copying the owner graph of the render target or by writing a custom
getOwnedItems()
. Here's how you would modify getSceneCopy
to work with the graph that owns the render target:- Code: Select all
-- Returns copies of the original scene graph, the camera node and the rendertarget.
-- This prevents us from modifying the original scene.
function getSceneCopy()
-- Get the selected render target and check it
local selectedRt = octane.project.getSelection()[1]
if not selectedRt or selectedRt:getProperties().type ~= octane.NT_RENDERTARGET then
showError("TurntableG Error!","no render target selected", true)
end
-- Get the graph that owns the rt node (THIS IS WHAT CHANGED HERE!)
local ownerGraph = selectedRt:getProperties().graphOwner
print(ownerGraph)
-- find the index of the selected render target node
local idx = -1
for i, item in ipairs(ownerGraph:getOwnedItems()) do
if item == selectedRt then
idx = i
break
end
end
-- see if we could find the node
if idx == -1 then showError("TurntableG Error!","no render target selected", true) end
-- create a full copy of the project so that we don't modify the original project
local copyScene = octane.nodegraph.createRootGraph("Project Copy")
copyScene:copyFromGraph(ownerGraph)
copies = copyScene:getOwnedItems()
copyRt = copies[idx]
-- check if the copied node is a render target with a thinlens camera connected to it
if not copyRt or copyRt:getProperties().type ~= octane.NT_RENDERTARGET then
showError("TurntableG Error!","no render target selected", true)
end
-- check if a thin lens camera is connected to the render target
local copyCam = copyRt:getInputNode(octane.P_CAMERA)
if not copyCam or copyCam :getProperties().type ~= octane.NT_CAM_THINLENS then
showError("TurntableG Error!","no thinlens camera connected to the render target", true)
end
-- Find all render targets
local renderTargets = octane.nodegraph.getRootGraph():findNodes(octane.NT_RENDERTARGET)
local renTargList = {}
for i, item in ipairs(renderTargets) do
-- renTargList[item:getProperties().name] = item
renTargList[#renTargList + 1] = item:getProperties().name
end
return copyScene, copyRt, copyCam, renTargList
end
The downside of the above method is that when the camera is in the root scene graph but the render target is nested in another graph, the original camera is modified by this script.
Another approach would be the create a function that returns all the items, including the nested items. This would work like this:
- Code: Select all
-- Returns all the items, even those owned by nested graphs.
local function getAllItems(graph)
local all = {}
for i, item in ipairs(graph:getOwnedItems()) do
-- for graphs we recursively collect all the items
if item:getProperties().isGraph then
local nested = getAllItems(item)
-- merge the tables
for j, nestedItem in ipairs(nested) do
table.insert(all, nestedItem)
end
else
table.insert(all, item)
end
end
return all
end
-- Returns copies of the original scene graph, the camera node and the rendertarget.
-- This prevents us from modifying the original scene.
function getSceneCopy()
-- get the selected render target
local selectedRt = octane.project.getSelection()[1]
-- find the index of the selected render target node
local idx = -1
for i, item in ipairs(getAllItems(octane.nodegraph.getRootGraph())) do
if item == selectedRt then
idx = i
break
end
end
-- see if we could find the node
if idx == -1 then showError("TurntableG Error!","no render target selected", true) end
-- create a full copy of the project so that we don't modify the original project
local copyScene = octane.nodegraph.createRootGraph("Project Copy")
copyScene:copyFrom(octane.nodegraph.getRootGraph():getOwnedItems())
copies = getAllItems(copyScene)
copyRt = copies[idx]
-- check if the copied node is a render target with a thinlens camera connected to it
if not copyRt or copyRt:getProperties().type ~= octane.NT_RENDERTARGET then
showError("TurntableG Error!","no render target selected", true)
end
-- check if a thin lens camera is connected to the render target
local copyCam = copyRt:getInputNode(octane.P_CAMERA)
if not copyCam or copyCam :getProperties().type ~= octane.NT_CAM_THINLENS then
showError("TurntableG Error!","no thinlens camera connected to the render target", true)
end
-- Find all render targets
local renderTargets = octane.nodegraph.getRootGraph():findNodes(octane.NT_RENDERTARGET)
local renTargList = {}
for i, item in ipairs(renderTargets) do
-- renTargList[item:getProperties().name] = item
renTargList[#renTargList + 1] = item:getProperties().name
end
return copyScene, copyRt, copyCam, renTargList
end
This is the most flexible, maybe we should add
getAllItems
to the API itself.I hope this helps to clarify things a bit.
cheers,
Thomas