Jump to: Board index » General » Fusion

Helper Function

Learn about 3D compositing, animation, broadcast design and VFX workflows.
  • Author
  • Message
Offline

purplemagic

  • Posts: 58
  • Joined: Tue Jan 05, 2021 9:23 pm
  • Real Name: Justin Lewis

Helper Function

PostTue Apr 27, 2021 3:21 am

I created a helper function in a lua script that will be accessed by several composites across projects through SimpleExpression.

Where do I put this script and how do I make it available?

I have a programming background but I'm relatively new to Fusion scripting.

Thanks.
Offline
User avatar

Jacob Danell

  • Posts: 298
  • Joined: Tue Aug 28, 2012 2:25 pm
  • Location: Sweden

Re: Helper Function

PostTue Apr 27, 2021 8:48 am

Do you mean you have created a script that automates stuff or a function that should be used in other scripts/expressions?

If you have made a script you should place them in:
Code: Select all
Linux: ~/.fusion/BlackmagicDesign/Fusion/Scripts/Comp (or Tool)

OSX: ~/Library/Application Support/Blackmagic Design/Scripts/Comp (or Tool)

Windows: %appdata%\Blackmagic Design\Scripts\Comp (or Tool)


If you have crated more of a helper function, rename the extension to .scriptlib and place it directly in the scripts folder. That way functions inside that file will be accessible in any other script :)

Windows 10, Fusion 18.x
AMD Ryzen 9 5950X 16-Core Processor 3.40 GHz
Nvidia GeForce RTX 3090 Ti
128 GB ram
Offline
User avatar

Bryan Ray

  • Posts: 2491
  • Joined: Mon Nov 28, 2016 5:32 am
  • Location: Los Angeles, CA, USA

Re: Helper Function

PostTue Apr 27, 2021 4:00 pm

I don't think simple expressions get access to the scope where a function in a scriptlib lives. I made a couple of attempts to load bmd.scriptlib in an expression, and in the frame render script, but I couldn't make it work. Which is not to say that it's impossible, only that I couldn't figure it out within ten minutes.
Bryan Ray
http://www.bryanray.name
http://www.sidefx.com
Offline

purplemagic

  • Posts: 58
  • Joined: Tue Jan 05, 2021 9:23 pm
  • Real Name: Justin Lewis

Re: Helper Function

PostFri Apr 30, 2021 6:42 am

Jacob Danell wrote:If you have crated more of a helper function, rename the extension to .scriptlib and place it directly in the scripts folder. That way functions inside that file will be accessible in any other script :)


I created a scriptlib file with the following code and then placed it in C:\Users\<username>\AppData\Roaming\Blackmagic Design\DaVinci Resolve\Support\Fusion\Scripts.
Code: Select all
fuction test()
   return 1;
end

The path is slightly different from yours but there are subfolders created by Davinci Resolve such as Comp, Tool, and Utility so it looks like it's the right one.

I put the following code in the Size property of a Transform node.
Code: Select all
test()


But I get an error, the same one you get when you mistype something. What did I do wrong here?
Offline
User avatar

Jacob Danell

  • Posts: 298
  • Joined: Tue Aug 28, 2012 2:25 pm
  • Location: Sweden

Re: Helper Function

PostFri Apr 30, 2021 8:51 am

For the Fusion page in Resolve Lite or Resolve Studio use these UserData folders:

Linux: ~/.local/share/DaVinciResolve/Fusion/Scripts
OSX: ~/Library/Application Support/Blackmagic Design/DaVinci Resolve/Scripts
Windows: %appdata%\Blackmagic Design\DaVinci Resolve\Fusion\Scripts


so it seems like you have installed it correctly. I'm not using Resolve Studio myself but hopefully someone else knows what's going on.

Windows 10, Fusion 18.x
AMD Ryzen 9 5950X 16-Core Processor 3.40 GHz
Nvidia GeForce RTX 3090 Ti
128 GB ram
Offline
User avatar

Bryan Ray

  • Posts: 2491
  • Joined: Mon Nov 28, 2016 5:32 am
  • Location: Los Angeles, CA, USA

Re: Helper Function

PostFri Apr 30, 2021 3:03 pm

As I said, a simple expression doesn't get access to the full scope of the scripting environment. To verify that your scriptlib is working, try first invoking your function from the Console. If it works there, then you know it's in the right place. But you still won't be able to call it from within your tool, as far as I can tell.

I tried invoking a scriptlib in the Frame Render script with dofile(), even, and that didn't work, either.
Bryan Ray
http://www.bryanray.name
http://www.sidefx.com
Offline

purplemagic

  • Posts: 58
  • Joined: Tue Jan 05, 2021 9:23 pm
  • Real Name: Justin Lewis

Re: Helper Function

PostFri Apr 30, 2021 10:18 pm

Bryan Ray wrote:As I said, a simple expression doesn't get access to the full scope of the scripting environment. To verify that your scriptlib is working, try first invoking your function from the Console. If it works there, then you know it's in the right place.

I get the following error if I call a function test() in the scriblib file from the console or a comp script.
Code: Select all
attempt to call global 'test' (a nil value)

But I can confirm that the code inside the scriptlib does run when I run any comp script.

The problem is I can't call a function in the scriptlib from within a comp script. Is this normal?
Offline
User avatar

Bryan Ray

  • Posts: 2491
  • Joined: Mon Nov 28, 2016 5:32 am
  • Location: Los Angeles, CA, USA

Re: Helper Function

PostFri Apr 30, 2021 11:33 pm

You may need to assign it to a namespace. Check out how the bmd.scriptlib is constructed. It starts by using a table constructor to make the bmd namespace, then each function is an entry in the table.
Bryan Ray
http://www.bryanray.name
http://www.sidefx.com
Offline

purplemagic

  • Posts: 58
  • Joined: Tue Jan 05, 2021 9:23 pm
  • Real Name: Justin Lewis

Re: Helper Function

PostFri Apr 30, 2021 11:59 pm

Bryan Ray wrote:You may need to assign it to a namespace. Check out how the bmd.scriptlib is constructed. It starts by using a table constructor to make the bmd namespace, then each function is an entry in the table.

I have Davinci Resolve 16 for Windows, but for some reason, it does not have bmd.scriptlib. I did a search on the entire hard drive and couldn't find it. Is the bmd.scriptlib for the standalone Fusion only? Where can I get it?

Also, neither the Fusion 8 Scripting Guide nor DaVinci Resolve 16.1 Reference Manual mention namespace. Do you have any examples?

Thanks.
Offline
User avatar

Bryan Ray

  • Posts: 2491
  • Joined: Mon Nov 28, 2016 5:32 am
  • Location: Los Angeles, CA, USA

Re: Helper Function

PostSat May 01, 2021 2:03 pm

Peculiar. It seems that the default scripts that are usually in the program folders are not included with Resolve. I guess that explains why they never noticed that Bake Animation is broken—they're not distributing it with the product that they actually pay attention to.

Here's bmd.scriptlib:

Code: Select all


-----------------------------------------------------
-- bmd.scriptlib
--
-- $Revision$
-- Last Modified : $Date$
-- Description : Common routines used by FuScript
--
-----------------------------------------------------


bmd = bmd or {}  -- namespace that things should be put in

bmd.version = string.sub([[$Revision$]], 12, -2)


-----------------------------------------------------
-- convertIDtoChar(x)
--
-- several attrs in DF return ID values which are four
-- characters combined into a single 32 bit number. To
-- make life difficult, they are also swapped from
-- normal reading order. This function decodes them
-- into a string
--
-- introduced Blackmagic.dfscriptlib v1.0
-----------------------------------------------------
function bmd.convertIDtoChar(x)
 return string.format("%c%c%c%c", x - floor(x / 256)*256, floor(x / 256) - floor(x / (256*256))*256, floor(x / (256*256)) - floor(x / (256*256*256))*256, floor(x / (256*256*256)))
end

-----------------------------------------------------
-- split(strInput, delimit)
--
-- converts string strInput into a table, separating
-- records using the provided delimiter string
--
-----------------------------------------------------
function bmd.split(strInput, delimit)
   local strLength
   local strTemp
   local strCollect
   local tblSplit
   local intCount

   tblSplit = {}
   intCount = 0
   strCollect = ""
   if delimit == nil then
      delimit = ","
   end

   strLength = string.len(strInput)
   for i = 1, strLength do
      strTemp = string.sub(strInput, i, i)
      if strTemp == delimit then
         intCount = intCount + 1
         tblSplit[intCount] = trim(strCollect)
         strCollect = ""
      else
         strCollect = strCollect .. strTemp
      end
   end
   intCount = intCount + 1
   tblSplit[intCount] = trim(strCollect)

   return tblSplit
end

-----------------------------------------------------
-- trim(strTrim)
--
-- returns strTrim with leading and trailing spaces
-- removed.
--
-- introduced bmd.dfscriptlib v1.0
-- last updated in v1.3
-----------------------------------------------------
function bmd.trim(strTrim)
   strTrim = string.gsub(strTrim, "^(%s+)", "") -- remove leading spaces
   strTrim = string.gsub(strTrim, "(%s+)$", "") -- remove trailing spaces
   return strTrim
end

-----------------------------------------------------
-- GetLoaders(composition)
--
-- returns a table of loader tools from the comp
--
-- introduced bmd.scriptlib v2.0
-- last updated in v2.1
-----------------------------------------------------
function bmd.GetLoaders(composition)
   return composition:GetToolList(false, "Loader")
end

-----------------------------------------------------
-- GetSavers(composition)
--
-- returns a table of saver tools from comp
--
-- introduced bmd.dfscriptlib v1.0
-- last updated in v2.1
-----------------------------------------------------
function bmd.GetSavers(composition)
   return composition:GetToolList(false, "Saver")
end



-----------------------------------------------------
-- fprint(...)
--
-- prints a list of arguments, formatted into columns
--
-- introduced Blackmagic.dfscriptlib v1.10
-----------------------------------------------------
function bmd.fprint(...)
   local ret = {}
   for i, v in {...} do
      v = tostring(v)
      ret[i] = string.format("%-25.25s", v)
   end
   print(unpack(ret))
end


-----------------------------------------------------
-- isin(t, val)
--
-- scans table t and returns true if the string val is
-- found in the table.
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.isin(t, val)
   if type(t) == "table" then
      for i,v in pairs(t) do
         if (type(v) == "string") and (type(val) == "string") then
            if string.lower(v) == string.lower(val) then
               return true
            end
         else
            if v == val then
               return true
            end
         end
      end
   end

   return false
end

-----------------------------------------------------
-- get_table_index(t, val)
--
-- scans table t and returns nil if the string val is
-- not found in the table. Otherwise returns the index
-- of the record containing the value.
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.get_table_index(t, val)
   if type(t) == "table" then

      for i,v in pairs(t) do
         if string.lower(val) == string.lower(v) then
            return i
         end
      end
   end

   return nil
end

------------------------------------------------------------------------------
-- parseFilename()
--
-- this is a great function for ripping a filepath into little bits
-- returns a table with the following
--
-- FullPath   : The raw, original path sent to the function
-- Path      : The path, without filename
-- FullName   : The name of the clip w\ extension
-- Name     : The name without extension
-- CleanName: The name of the clip, without extension or sequence
-- SNum      : The original sequence string, or "" if no sequence
-- Number    : The sequence as a numeric value, or nil if no sequence
-- Extension: The raw extension of the clip
-- Padding   : Amount of padding in the sequence, or nil if no sequence
-- UNC      : A true or false value indicating whether the path is a UNC path or not
------------------------------------------------------------------------------
function bmd.parseFilename(filename)
   local seq = {}
   seq.FullPath = filename
   string.gsub(seq.FullPath, "^(.+[/\\])(.+)", function(path, name) seq.Path = path seq.FullName = name end)
   string.gsub(seq.FullName, "^(.+)(%..+)$", function(name, ext) seq.Name = name seq.Extension = ext end)

   if not seq.Name then -- no extension?
      seq.Name = seq.FullName
   end

   string.gsub(seq.Name,     "^(.-)(%d+)$", function(name, SNum) seq.CleanName = name seq.SNum = SNum end)

   if seq.SNum then
      seq.Number = tonumber( seq.SNum )
      seq.Padding = string.len( seq.SNum )
   else
      seq.SNum = ""
      seq.CleanName = seq.Name
   end

   if seq.Extension == nil then seq.Extension = "" end
   seq.UNC = ( string.sub(seq.Path, 1, 2) == [[\\]] )

   return seq
end

-----------------------------------------------------
-- getextension(name)
--
-- returns the portion of the filename after the
-- extension, minus the "."
--
-- included for compatibility - use parseFilename instead
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.getextension(filename)
   local i = ""
    string.gsub(filename, "%.(.+)$", function(r) i = r end)
   return i
end

-----------------------------------------------------
-- getfilepath(path)
--
-- returns the portion of the string path
-- up to and including the last "\" or "/" in the string
--
-- included for compatibility - use parseFilename instead
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.getfilepath(path)
   for i = string.len(path), 1, -1 do
      teststring = string.sub(path, i, i)
      if teststring == "\\" or teststring == "/" then
         return string.sub(path, 1, i)
      end
   end
end

-----------------------------------------------------
-- getfilename(path)
--
-- returns the portion of the string path after the
-- last "\" or "/" in the string
--
-- included for compatibility - use parseFilename instead
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.getfilename(path)

   for i = string.len(path), 1, -1 do
      teststring = string.sub(path, i, i)
      if teststring == "\\" or teststring == "/" then
         return string.sub(path, i+1)
      end
   end
end

-----------------------------------------------------
-- trimExtension(path)
--
-- returns the portion of the string filename up to
-- but not including the last "."
--
-- included for compatibility - use parseFilename instead
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.trimExtension(filename)
   for i = string.len(filename), 1, -1 do
      if string.sub(filename, i, i) == "." then
         period_loc = i
         break
      end
   end

   return string.sub(filename, 1, period_loc-1)

end

-----------------------------------------------------
-- trimSequence(path)
--
-- given a filename, this function will look for sequence
-- numbers in the name : e.g. image0001.tga
-- it returns a string with a copy of the filename minus
-- any numerical sequence numbers : e.g. image.tga
--
-- included for compatibility - use parseFilename instead
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.trimSequence(filename)
   -- get the name without the extension

   for i = string.len(filename), 1, -1 do
      if string.sub(filename, i, i) == "." then
         period_loc = i
         break
      end
   end

   for i = period_loc-1, 1, -1 do
      if tonumber(string.sub(filename, i, i)) == nil then
         name_loc = i
         break
      end
   end

   if string.sub(filename, name_loc, name_loc) == "." then
      name_loc = name_loc - 1
   end

   return string.sub(filename, 1, name_loc) .. string.sub(filename, period_loc)

end

-----------------------------------------------------
-- CopyCineonSettings(source, dest)
--
-- function removed in bmd.dfscriptlib 1.3
-- it was too specific to belong here.
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
function bmd.CopyCineonSettings(source, dest)
   error("this function has been removed from bmd.scriptlib. Please contact tech@blackmagicdesign.com if you need a copy of the function for a script you are using.")
end

-----------------------------------------------------
-- printf(...)
--
-- emulates the c function printf
--
-- introduced bmd.dfscriptlib v1.0
-----------------------------------------------------
-- global function
function globals.printf(fmt, ...)
    print(fmt:format(...))
end

-----------------------------------------------------
-- pathIsMovieFormat(path)
--
-- Indicates whether a path's extension is a movie
-- format.
--
-- introduced bmd.scriptlib v2.0
-----------------------------------------------------

function bmd.pathIsMovieFormat(path)
   local extension = getextension(path)
   if extension ~= nil then
      if      ( extension == ".avi" ) or ( extension == ".vdr" ) or ( extension == "wav" ) or
            ( extension == ".dvs" ) or
            ( extension == ".fb"  ) or
            ( extension == ".omf" ) or ( extension == ".omfi" ) or
            ( extension == ".stm" ) or
            ( extension == ".tar" ) or
            ( extension == ".vpv" ) or
            ( extension == ".mov" ) then
         return true
      end
   end
   return false
end

------------------------------------------------------------------------------
-- SV_GetFrames(sv)
--
-- This function takes a Saver and returns a table containing the names of
-- the frames the saver will actually output. If the tool provided is not a
-- saver or the saver has never been set up then the return value is nil.
--
-- introduced bmd.dfscriptlib v1.3
------------------------------------------------------------------------------
function bmd.SV_GetFrames(sv)

   local fla = sv.Composition:GetAttrs()

   if sv.ID ~= "Saver" then
      return nil, "The tool "..sv.Name.." is not a Saver tool."
   end

   if sv.Normal[fu.TIME_UNDEFINED] == 1 then
      return nil, sv.Name.." is set to 2:3 pulldown. This function does not support pulldown."
   end

   -- its safe to assume [0] for Clipname since savers have no cliplists
   local sv_file = sv.Clip[0]

   if sv_file == "" then
      return nil, sv.Name.." does not yet have a filename to save to."
   end

   -- multiframe clips only have one filename
   if pathIsMovieFormat (sv.Clip[0]) == true then
      return {sv_file}
   end

   local seq = bmd.parseFilename(sv_file)

   -- Saver has a control to force the starting sequence number.
   if sv.SetSequenceStart[fu.TIME_UNDEFINED] == 0 then
      start = fla.COMPN_RenderStart
   else
      start = sv.SequenceStartFrame[fu.TIME_UNDEFINED]
               + fla.COMPN_RenderStart
               - fla.COMPN_GlobalStart
   end

   local length = fla.COMPN_RenderEnd - fla.COMPN_RenderStart

   if seq.Padding == nil then
      -- never rendered, no numbering provided assume default fusion padding
      seq.Padding = 4
   end

   local files = {}
   for i = start, start + length do
      table.insert(files, seq.Path..seq.CleanName..string.format("%0"..seq.Padding.."d", i)..seq.Extension)
   end
   return files

end

------------------------------------------------------------------------------
-- LD_GetFrames(ld)
--
-- This function takes a Loader and returns a table containing the names of
-- the files the loader will actually load from disk. If the tool provided is not a
-- loader or the loader has never been set up return value is nil.
--
-- introduced bmd.dfscriptlib v1.3
------------------------------------------------------------------------------
function bmd.LD_GetFrames(ld)
   lda = ld:GetAttrs()

   -- is it a loader?
   if ld.ID ~= "Loader" then
      return nil, "The tool "..ld.Name.." is not a Loader tool."
   end

   if ld.ImportMode[fu.TIME_UNDEFINED] ~= 0 then
      return nil, "The tool "..ld.Name.." is set to pulldown or pullup. This function does not support these import modes."
   end

   if not lda.TOOLST_Clip_Name then
      return nil, "The tool "..ld.Name.." is not set up yet, the Loader is empty."
   end

   frames = {}

   for i, v in lda.TOOLST_Clip_Name do

      if lda.TOOLBT_Clip_IsMultiFrame[i] == 1 then
         table.insert(frames, v)
      else

         seq = bmd.parseFilename(v)
         if seq.Padding == nil then
            table.insert(frames, v )
         else
            for x = lda.TOOLIT_Clip_TrimIn[i], lda.TOOLIT_Clip_TrimOut[i] do
               frame = lda.TOOLIT_Clip_InitialFrame[i] + x
               table.insert(frames, seq.Path..seq.CleanName..string.format("%0"..seq.Padding.."d", frame)..seq.Extension )
            end
         end

      end

   end

   return frames

end

------------------------------------------------------------------------------
-- FUNCTION copyfile()
-- copy file from src_path to dest_path
------------------------------------------------------------------------------
function bmd.copyfile(src_path, dest_path)
   local read_size = 65536

   src, errMsg = io.open(src_path, "rb")
   if src == nil then
      return 0, "SOURCE : "..errMsg
   end

   local size = src:seek("end")
   src:seek("set")

   dest, errMsg = io.open(dest_path, "wb")
   if dest == nil then
      return 0, "DEST : "..errMsg
   end

   src_data = src:read(read_size)
   repeat
      dest:write(src_data)
      src_data = src:read(read_size)
   until src_data == nil

   src:close()
   dest:close()
   return size
end


function is_console_script(dotool)
   if not fusion then
      fusion = Fusion()
      if fusion == nil then error("Could not connect to Fusion") end
      composition = fusion:GetCurrentComp()
      if composition == nil then error("Could not connect to Fusion") end
      if not tool and ( dotool == true ) then
         tool = fusion:GetCurrentTool()
         if tool == nil then
            error("No currently active tool")
         end
      end
      return true
   else
      return false
   end
end


------------------------------------------------------------------------------
-- MoveClip
--
-- This function is used to move a clip and perform the correct order of
-- operations to preserve trimming.
--
-- introduced bmd.scriptlib v2.02
------------------------------------------------------------------------------

function bmd.MoveClip(loader, oldstart, newstart)
    -- Remember clip trimming values
    local globalin    = loader.GlobalIn[oldstart]
    local globalout   = loader.GlobalOut[oldstart]
    local clipstart   = loader.ClipTimeStart[oldstart]
    local clipend     = loader.ClipTimeEnd[oldstart]
    local extfirst    = loader.HoldFirstFrame[oldstart]
    local extlast     = loader.HoldLastFrame[oldstart]

    local len = globalout - globalin + 1

    if newstart > oldstart then -- Moving forwards
        loader.GlobalOut[oldstart] = newstart + len - 1
        loader.GlobalIn[oldstart] = newstart
    else -- Moving Backwards
        loader.GlobalIn[oldstart] = newstart
        loader.GlobalOut[newstart] = newstart + len - 1
    end

    -- Now fix our trimming
    loader.ClipTimeStart[newstart]     = clipstart
    loader.ClipTimeEnd[newstart]     = clipend
    loader.HoldFirstFrame[newstart]  = extfirst
    loader.HoldLastFrame[newstart]   = extlast
end


-- Expose our namespace
globals.bmd = bmd

-- expose some globals for compatibility :(
-- bmd.dfscriptlib functions were part of the globals
-- namespace until version 1.3 of the file.
-- this allows compatibility with that old method.

globals.convertIDtoChar = bmd.convertIDtoChar
globals.pathIsMovieFormat = bmd.pathIsMovieFormat
globals.split = bmd.split
globals.trim = bmd.trim
globals.GetLoaders = bmd.GetLoaders
globals.GetSavers = bmd.GetSavers
globals.isin = bmd.isin
globals.get_table_index = bmd.get_table_index
globals.getextension = bmd.getextension
globals.getfilepath = bmd.getfilepath
globals.getfilename = bmd.getfilename
globals.trimExtension = bmd.trimExtension
globals.trimSequence = bmd.trimSequence
globals.CopyCineonSettings = bmd.CopyCineonSettings
globals.MoveClip = bmd.MoveClip

-- some legacy compatibility
eyeon = bmd
globals.eyeon = bmd

-----------------------------------------------------
-- prefLib
--
-- $Revision$
-- Last Modified : $Date$
-- Description : Script Library that gives a standard
-- way to write out preferences for scripts.
--
-----------------------------------------------------


prefLib = {}

------------------------------------------------------------------------------
-- doPrefs (scriptName,readPrefs,developer,tPrefs)
--
-- scriptName = String Value, required -- set to the name of the script, ideally
-- readPrefs = Boolean Value, required -- whether you are reading or writing values, true if read
-- developer = String Value, optional -- used to keep the preferences folders
-- from being unwieldly.  Pass nil if you want it in the root.
-- tPrefs = Table value, required if writing -- table of values that relate
-- to preferences for the script.
--
-- This function is used to read and write functions to the ScriptPrefs file
-- that you'll be writing out.  The goal was to create a template for people
-- to work from so that it follows the 'rules' associated with Fusion profiles,
-- given that these rules can sometimes be a bit complex (using environment
-- variables, etc.).
--
------------------------------------------------------------------------------

function prefLib.doPrefs(scriptName,readPrefs,developer,tPrefs)
   if not scriptName then
      error("ERROR: You did not specify a scriptName.")
   end

   developer = developer and developer.."\\" or ""

   local f_dir = os.getenv("FUSION_PROFILE_DIR") or fusion:MapPath("Profiles:\\")
   local profileName = os.getenv("FUSION_PROFILE") or "Default"

   if f_dir:sub(-1)=="\\" then
      f_dir = f_dir:sub(1, -2)
   end

   local prefDir = f_dir.."\\"..profileName.."\\ScriptPrefs\\"..developer
   local prefFile = prefDir .. scriptName..".ScriptPrefs"

   if not bmd.direxists(prefDir) then
      bmd.createdir(prefDir)
   end

   if readPrefs then
      return bmd.readfile(prefFile)
   else
      if type(tPrefs) == "table" then
         bmd.writefile(prefFile, tPrefs)
      else
         error("ERROR: This function requires a table.")
      end
   end
end

-- Push the table to the globals environment.
globals.prefLib = prefLib



The line that creates the namespace is this one:
bmd = bmd or {} -- namespace that things should be put in

And then each function is an item in that table:
function bmd.MoveClip(loader, oldstart, newstart)…

This not only gives you a handle to address the functions, it also prevents name collisions from loading multiple libraries.
Bryan Ray
http://www.bryanray.name
http://www.sidefx.com
Offline

purplemagic

  • Posts: 58
  • Joined: Tue Jan 05, 2021 9:23 pm
  • Real Name: Justin Lewis

Re: Helper Function

PostSun May 02, 2021 6:21 am

Bryan Ray wrote:The line that creates the namespace is this one:
bmd = bmd or {} -- namespace that things should be put in

And then each function is an item in that table:
function bmd.MoveClip(loader, oldstart, newstart)…

This not only gives you a handle to address the functions, it also prevents name collisions from loading multiple libraries.

Thank you!

I was able to access my scriptlib from both comp and tool scripts.

Like you stated earlier, scriptlib files don't seem to run at all when Expression code runs. Is there a way around it though? Many of my composites share common code and it'd be cumbersome and errorprone to copy and paste it each time.
Offline
User avatar

Bryan Ray

  • Posts: 2491
  • Joined: Mon Nov 28, 2016 5:32 am
  • Location: Los Angeles, CA, USA

Re: Helper Function

PostMon May 03, 2021 3:38 am

I still haven't been able to do it. However, you might ask in the Scripting forum over at We Suck Less. It's entirely possible that somebody else knows the answer.

https://www.steakunderwater.com/wesuckl ... um.php?f=6
Bryan Ray
http://www.bryanray.name
http://www.sidefx.com
Offline

purplemagic

  • Posts: 58
  • Joined: Tue Jan 05, 2021 9:23 pm
  • Real Name: Justin Lewis

Re: Helper Function

PostWed May 05, 2021 12:36 am

Bryan Ray wrote:I still haven't been able to do it. However, you might ask in the Scripting forum over at We Suck Less. It's entirely possible that somebody else knows the answer.

Thanks, Bryan. I'll ask there.

Return to Fusion

Who is online

Users browsing this forum: No registered users and 37 guests