Page 1 of 1

Scripted graph animated mesh materials

PostPosted: Thu Aug 27, 2015 2:31 pm
by photonreality
Hi,

We are working with quite big >40GB Alembic files and unfortunately Octane 2.xx fails to animate/refresh some of them properly.

So, I have tried to make a scripted node graph that loads geometry mesh from separate OBJ files and it works fine.
What I haven't been able to figure out so far is how to connect materials to this scripted graph.
Even a single material input would be very helpful as an example.
This is the first LUA script that I am working with and it seems that for some reason I can't access/copy the materials using self:getInputValue(inputs[4]).
I would appreciate it a lot if someone could help me to get the materials working in this script.

Alternatively there can be input mesh "guide" node that is connected to several materials so that we could copy/connect many materials.

Best Regards,
Hando

Code: Select all
local AnimTexture = {}
local frameTime = 0

function getFrame(currentTime)
   return math.floor((currentTime + (frameTime / 2))/frameTime)
end


function AnimTexture.onInit(self, graph)
   graph:updateProperties({name = "Animated Mesh"})
   
  local inputInfos = {
     {type=octane.PT_STRING, label="File Name", defaultNodeType=octane.NT_FILE},
        {type=octane.PT_INT, label="Number of Digits", defaultNodeType=octane.NT_INT, defaultValue=3},
        {type=octane.PT_INT, label="Frames per Second", defaultNodeType=octane.NT_INT, defaultValue=30},
--        {type=octane.PT_MATERIAL, label="Material", defaultNodeType=octane.NT_IN_MATERIAL },
--        {type=octane.PT_GEOMETRY, label="Material Guide", defaultNodeType=octane.NT_GEO_MESH }
  }
         
   local outputInfos = {
    {type=octane.PT_GEOMETRY, label="Animated Mesh"}
  }
         
   inputs = graph:setInputLinkers(inputInfos)
   outputs = graph:setOutputLinkers(outputInfos)
   self:setEvaluateTimeChanges(true)
   
    mesh = octane.node.create{ type = octane.NT_GEO_MESH, name = "Anim Mesh", graphOwner=graph }

  outputs[1]:connectTo("input", mesh)
end

function AnimTexture.onEvaluate(self, graph)
   
  if self:timeWasChanged() then
     fileName = self:getInputValue(inputs[1])
   numDigits = self:getInputValue(inputs[2])
   sceneFps = self:getInputValue(inputs[3])

     frameTime = 1.0/sceneFps
     local frameNum = getFrame(graph.time)
   
     parentPath = octane.file.getParentDirectory(fileName)
     baseFile = octane.file.getFileNameWithoutExtension(fileName)
     fileExt = octane.file.getFileExtension(fileName)
     cleanFile = string.sub(baseFile, 1, baseFile:len() - numDigits)
   numFormat = "%0"..numDigits.."u"
   finalFile = octane.file.join(parentPath, cleanFile..string.format(numFormat, frameNum)..fileExt)

   mesh:setAttribute(octane.A_FILENAME, finalFile)
   mesh:setAttribute(octane.A_RELOAD, true)

   end

  return true
end

return AnimTexture

Re: Scripted graph animated mesh materials

PostPosted: Thu Aug 27, 2015 5:37 pm
by grimm
It's been awhile since I have looked at this stuff, but I have some things you could try. It looks like you are not passing the textures through the node, that is you need to also add them to the outputInfos table as well as the inputInfos table. Make sure that they are the right type. I'm not 100% sure this will work, but give it a try. :)

Re: Scripted graph animated mesh materials

PostPosted: Fri Aug 28, 2015 6:29 am
by photonreality
Well, this script loads a new OBJ file (mesh) for each frame in the animation.
I have specified an input for a single material like this:
{type=octane.PT_MATERIAL, label="Material", defaultNodeType=octane.NT_IN_MATERIAL }
and I can connect a material to this input using Octane GUI.

Now I would like the script to connect this material specified by the input (4) the mesh loaded and I don't know how to do that correctly inside the scripted graph.

Re: Scripted graph animated mesh materials

PostPosted: Mon Aug 31, 2015 9:09 am
by bepeg4d
Hi,
I have added a couple of lines to your script, now it search for a material called "Mat" in the scene and connect it to the in_material input:
Code: Select all
    local AnimTexture = {}
    local frameTime = 0

    function getFrame(currentTime)
       return math.floor((currentTime + (frameTime / 2))/frameTime)
    end


    function AnimTexture.onInit(self, graph)
       graph:updateProperties({name = "Animated Mesh"})
       
      local inputInfos = {
         {type=octane.PT_STRING, label="File Name", defaultNodeType=octane.NT_FILE},
            {type=octane.PT_INT, label="Number of Digits", defaultNodeType=octane.NT_INT, defaultValue=3},
            {type=octane.PT_INT, label="Frames per Second", defaultNodeType=octane.NT_INT, defaultValue=30},
            {
            type            = octane.PT_MATERIAL,
            label           = "Material-in",
            fromNodeType    = octane.NT_IN_MATERIAL,
            fromPinId       = octane.P_INPUT
        }

    --        {type=octane.PT_MATERIAL, label="Material", defaultNodeType=octane.NT_IN_MATERIAL },
    --        {type=octane.PT_GEOMETRY, label="Material Guide", defaultNodeType=octane.NT_GEO_MESH }
      }
             
       local outputInfos = {
        {type=octane.PT_GEOMETRY, label="Animated Mesh"}
      }
             
       inputs = graph:setInputLinkers(inputInfos)
       outputs = graph:setOutputLinkers(outputInfos)
       self:setEvaluateTimeChanges(true)
       
        mesh = octane.node.create{ type = octane.NT_GEO_MESH, name = "Anim Mesh", graphOwner=graph }

      outputs[1]:connectTo("input", mesh)
      sceneGraph = octane.project.getSceneGraph()
      Mater = octane.nodegraph.findItemsByName(sceneGraph, "Mat", false)
      inputs[4] : connectTo (octane.P_INPUT, Mater[1])
    end

    function AnimTexture.onEvaluate(self, graph)
   
       
      if self:timeWasChanged() then
         fileName = self:getInputValue(inputs[1])
       numDigits = self:getInputValue(inputs[2])
       sceneFps = self:getInputValue(inputs[3])

         frameTime = 1.0/sceneFps
         local frameNum = getFrame(graph.time)
       
         parentPath = octane.file.getParentDirectory(fileName)
         baseFile = octane.file.getFileNameWithoutExtension(fileName)
         fileExt = octane.file.getFileExtension(fileName)
         cleanFile = string.sub(baseFile, 1, baseFile:len() - numDigits)
       numFormat = "%0"..numDigits.."u"
       finalFile = octane.file.join(parentPath, cleanFile..string.format(numFormat, frameNum)..fileExt)

       mesh:setAttribute(octane.A_FILENAME, finalFile)
       mesh:setAttribute(octane.A_RELOAD, true)

       end

      return true
    end

    return AnimTexture

ciao beppe