Callback function from button cannot call node inside array

Forums: Callback function from button cannot call node inside array
Forum for OctaneRender Lua scripting examples, discussion and support.

Callback function from button cannot call node inside array

Postby diatom » Fri May 15, 2020 3:34 am

diatom Fri May 15, 2020 3:34 am
New lua scripter here. Forgive my naivete in advance.
I am making a script that will get all the render targets in the scene graph that contain panoramic cameras, and then collect data (position, etc), and save it to a json file.
The gui makes a set of buttons for each pano camera found. One will select the render target node and then update the render viewport.
I am looping through an array (of render target nodes) to create my gui elements. The problem arises when I want to pass index data into the button callback.
The callback function can see global variables, but is not able to retain the value of my index variable (c).
How can I get my callback function to reference an item in an array?
If this cannot work, is there a better way to approach this?

Thanks
Thomas

Code: Select all
-- Make an array of all cameras and their render node names
panoCams = {};
renderTarget = {}; -- render target that contains the pano camera
p=1;
-- Get all the render target nodes in the scene
nodes = octane.nodegraph.findNodes( octane.project.getSceneGraph(), octane.NT_RENDERTARGET, true );
-- Refine the render targets to only those with pano cameras
for i, entry in ipairs(nodes) do
   -- print(entry)
    cam = octane.node.getConnectedNodeIx( entry, 1 );
   -- print(cam, cam.nodeType, octane.node.getNodeInfo(cam))
    if cam.nodeType == 62 then -- CAM_PANORAMIC
        panoCams[p] = cam;
        renderTarget[p] = entry;
     
       -- print(p, panoCams[p], entry.name);
        p=p+1;
    end
end

-----------------------------------------------------------------------------------------

panoGroups = {};
panoCaptions = {};
panoOpen = {};
renButtonProps = {};
gTest = "test";
c = 1;
for index, value in ipairs(panoCams) do
    local i = (index-1) * 4
    print(index,  i, ':', panoCams[index], ':', renderTarget[index].name);
    local camlabel       = createLabel("Pano Camera ".. index);
    local renlabel       = createLabel("Render Target "..renderTarget[index].name);

    print('render target: ', c, renderTarget[c].name);

    -- create a button to show a file chooser
    local renderTargetButton = octane.gui.create
    {
        type     = octane.gui.componentType.BUTTON,
        text     = "Render View",
        width    = 80,
        height   = 20,
        callback =
        -- Select the render target
        function(component, event)   
            print('component: ', component);
            print('select render target: ', renderTarget[1].name);  --  *** HERE is where I'd like the index variable c to go, but it returns nil.
            octane.project.clearSelection();
            octane.project.select(renderTarget[1]);
            --octane.render.restart();
           -- octane.render.start {    renderTargetNode = renderTarget[1] };
        end
    }

   
     -- create a button to show a file chooser
    local loadImageButton = octane.gui.create
    {
        type     = octane.gui.componentType.BUTTON,
        text     = "Image Path",
        width    = 80,
        height   = 20,
    }
   
   -- panoGroups[index] = { camlabel, renlabel, fileChooseButton, loadImageButton };
    panoGroups[i+1] =  camlabel;
    panoGroups[i+2] =  renlabel;
    panoGroups[i+3] =  renderTargetButton;
    panoGroups[i+4] =  loadImageButton;

   
    c=c+1
end
diatom
Licensed Customer
Licensed Customer
 
Posts: 12
Joined: Fri Jul 22, 2016 7:07 am

Re: Callback function from button cannot call node inside array

Postby diatom » Fri May 15, 2020 11:21 pm

diatom Fri May 15, 2020 11:21 pm
I figured out a workaround. I can pass the index (c) into the callback function by assigning the text property of the button to the index as text, then convert it to a number inside the callback.
Not pretty, but it works.
Code: Select all
 -- create a button to render target to viewport
    local renderTargetButton = octane.gui.create
    {
        type     = octane.gui.componentType.BUTTON,
        text     = tostring(c),
       callback =
        function(component, event)   
            local id = tonumber(octane.gui.getProperties(component).text);
            print('select render target: ', renderTarget[id].name);
        end



I'll post a working version of this when it is finished.
Thomas
diatom
Licensed Customer
Licensed Customer
 
Posts: 12
Joined: Fri Jul 22, 2016 7:07 am

Re: Callback function from button cannot call node inside array

Postby jobigoud » Sat May 16, 2020 9:55 am

jobigoud Sat May 16, 2020 9:55 am
If you assign `c` or `renderTarget[c]` to a local variable inside the loop it should be captured by the callback closure.
User avatar
jobigoud
OctaneRender Team
OctaneRender Team
 
Posts: 48
Joined: Sat Aug 15, 2015 1:28 pm

Re: Callback function from button cannot call node inside array

Postby diatom » Mon May 18, 2020 7:28 pm

diatom Mon May 18, 2020 7:28 pm
Thank you jobigoud!
That worked.
Importantly, the variable has to be local AND
you must return a function that contains that variable to create the closure.

Code: Select all
local id = c; -- stored the global int c in the upvalue id
octane.project.select(renderTarget[id]); -- Access the global array renderTargetusing upvalue [id]

 return function()
           print('select render target: ', renderTarget[id].name);
 end


Thanks for the link to the explanation of closure. Now it all makes sense.
diatom
Licensed Customer
Licensed Customer
 
Posts: 12
Joined: Fri Jul 22, 2016 7:07 am

Re: Callback function from button cannot call node inside array

Postby diatom » Tue May 19, 2020 5:19 am

diatom Tue May 19, 2020 5:19 am
Here is my working version of the script.
It finds all the panoramic cameras in the scene and saves some data : camera positions, names of views, rendered image file paths,
to a json file. I'm using this in another web app, that works with panoramas.

Thomas
Attachments
panoCamDataToJson.zip
(12.09 KiB) Downloaded 6 times
diatom
Licensed Customer
Licensed Customer
 
Posts: 12
Joined: Fri Jul 22, 2016 7:07 am

Return to Lua Scripting


Who is online

Users browsing this forum: No registered users and 2 guests

Fri Jul 03, 2020 9:07 pm [ UTC ]