Jump to: Board index » General » Fusion

Is bmd.readfile() broken in Python 3?

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

DavidSE

  • Posts: 11
  • Joined: Wed Mar 03, 2021 6:13 pm
  • Real Name: David Rehnstrom

Is bmd.readfile() broken in Python 3?

PostWed Dec 29, 2021 7:35 pm

Hello everyone.

Built in console:
[in] fusion.LoadComp(path)

But no node turns up.


[in] fusion.LoadComp() #same as above accept path is omitted.

Opens up a file handler that prompts me to choose a composition to load. No node turns up this time ether tho.


"File --> Import --> Fusion Composition" works fine tho so at least the .comp file seems intact.


As I Understand from both the Fusion 8 scripting manual and all my googling, I am using this correctly so now I am beginning to suspect LoadComp() of being broken.
Anny thoughts or experience on this?
Last edited by DavidSE on Sun Jan 09, 2022 2:00 pm, edited 3 times in total.
Offline
User avatar

Andrew Hazelden

  • Posts: 596
  • Joined: Sat Dec 06, 2014 12:10 pm
  • Location: West Dover, Nova Scotia, Canada

Re: Is fusion.LoadComp() broken?

PostWed Dec 29, 2021 8:46 pm

DavidSE wrote:As I Understand from both the Fusion 8 scripting manual and all my googling, I am using this correctly so now I am beginning to suspect LoadComp() of being broken. Any thoughts or experience on this?


Hi DavidSE.

I'm pretty sure that code still runs fine in Fusion Studio to this very day... ;)

So, is this a question about how to use the Fusion scripting guide to load an external .comp file into Fusion Studio? Or is it a question about the Resolve Fusion page? There are implementation specific differences between both environments that are relevant.

In Resolve, one would need to clarify if you are trying to script the process of importing an external .comp file into a new independent Fusion composite that would exist in the Media Pool, or are trying to add that Fusion page comp data to an Edit page based timeline clip?

If any movie files are accessed via Loader or Saver nodes in the imported .comp file, you'll have some node based translation steps that are required in Resolve, too. Same thing goes for needing to expand any "Comp:/" based relative PathMaps into absolute file paths in the Resolve Fusion page on import.

KartaVR Comp DragDrop for Resolve Example

https://imgur.com/a/qSoIUVR



If you simply want a DIY approach to ingest external nodes from a .comp file into the active foreground Fusion page session in Resolve, you could take a look at the following "Config:/DragDrop/KartaVR Comp DragDrop.fu" PathMap based .fu file example that uses a Drag and Drop "action" to do that task:

https://gitlab.com/WeSuckLess/Reactor/-/blob/master/Atoms/com.AndrewHazelden.KartaVR.DragDrop/Config/DragDrop/KartaVR%20Comp%20DragDrop.fu
Reactor.lua:933: attempt to index global 'ui' (a nil value)
Offline

DavidSE

  • Posts: 11
  • Joined: Wed Mar 03, 2021 6:13 pm
  • Real Name: David Rehnstrom

Re: Is fusion.LoadComp() broken?

PostTue Jan 04, 2022 4:35 pm

Thank you Andrew for your extensive reply. I had to digest it for a while to fully understand.

I did not realize there is a difference between the studio version and the page in Resolve. Do you know of any resource describing the difference?

LoadComp() seems not to be what I am looking for.
What I want to do is something like:
>>> path_to_file = "some_folder\saved_tool.settings"
>>> comp.AddTool(path_to_file)

In other words, I want to save a node or a collection of nodes in a text file and add them with a script.

During the digestion I found comp.Paste() so with an extra step of first loading the file to the clipboard the problem is solved.


Edit: Forgot to say that I am using the Fusion page in Resolve.
Offline
User avatar

Andrew Hazelden

  • Posts: 596
  • Joined: Sat Dec 06, 2014 12:10 pm
  • Location: West Dover, Nova Scotia, Canada

Re: Is fusion.LoadComp() broken?

PostTue Jan 04, 2022 5:10 pm

DavidSE wrote:In other words, I want to save a node or a collection of nodes in a text file and add them with a script.

During the digestion I found comp.Paste() so with an extra step of first loading the file to the clipboard the problem is solved.


Here is a Steakunderwater forum post about Python scripting inside of Fusion that has a code snippet for adding a .setting file into a foreground comp. There are several other useful code snippets on that page which can be of use for general utility tasks.

https://www.steakunderwater.com/wesuckl ... 531#p12531

LoadMacro.py Script Example:
Code: Select all
    # Stop Loader/Saver node file dialogs from showing
    comp.Lock()
     
    # Translate a relative PathMap location into a filepath:
    macroFilePath = comp.MapPath('Macros:/example.setting')
    print('[Macro File] ' + macroFilePath)
     
    # Read the macro file into a variable
    macroContents = bmd.readfile(macroFilePath)
    print('[Macro Contents]\n' + str(macroContents))
     
    # Add the macro to your foreground comp
    comp.Paste(macroContents)
     
    # Allow Loader/Saver node file dialogs to show up again
    comp.Unlock()



Note: A Fusion macro based .setting file, and a .comp file are both stored on disk as ASCII formatted text in a layout called a Lua table.

You can easily copy any nodes from the active Fusion node graph into your copy/paste clipboard and then save them in your favorite text editor as a document with the .setting extension. This text snippet is then able to be used as a macro like element, a Resolve effects template, or a title template in future comps.
Reactor.lua:933: attempt to index global 'ui' (a nil value)
Offline
User avatar

Andrew Hazelden

  • Posts: 596
  • Joined: Sat Dec 06, 2014 12:10 pm
  • Location: West Dover, Nova Scotia, Canada

Re: Is fusion.LoadComp() broken?

PostWed Jan 05, 2022 12:10 pm

DavidSE wrote:I did not realize there is a difference between the studio version and the page in Resolve. Do you know of any resource describing the difference?


While not an answer to that specific question, BMD's official documentation on scripting in Resolve/Fusion can be found on your hard disk at:

Code: Select all
C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Workflow Integrations\README.txt

C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting\README.txt


* * *

The unofficial documentation effort to explore UI Manager, along with "Actions & Event" callbacks in Resolve/Fusion can be found on the Steakunderwater Fusion community forum thread here:

Building GUIs With Fusion's UI Manager
Reactor.lua:933: attempt to index global 'ui' (a nil value)
Offline

DavidSE

  • Posts: 11
  • Joined: Wed Mar 03, 2021 6:13 pm
  • Real Name: David Rehnstrom

Re: Is fusion.LoadComp() broken?

PostThu Jan 06, 2022 12:25 pm

This is exactly what I was looking for but it does not work for me. No node is pasted to the nodes window.

Code: Select all
# Stop Loader/Saver node file dialogs from showing
comp.Lock()
 
# Translate a relative PathMap location into a filepath:
macroFilePath = comp.MapPath(r'C:\Users\david\DVR/Text1.setting')
print('[Macro File] ' + macroFilePath)
 
# Read the macro file into a variable
macroContents = bmd.readfile(macroFilePath)
print('[Macro Contents]\n' + str(macroContents))
 
# Add the macro to your foreground comp
comp.Paste(macroContents)
 
# Allow Loader/Saver node file dialogs to show up again
comp.Unlock()


OUT:
Code: Select all
[Macro File] C:\Users\david\DVR\Text1.setting
[Macro Contents]
{'Tools': OrderedDict([])}



If I at the moment of running LoadMacro.py have a node in the clipboard than that node is pasted, otherwise nothing is pasted. Seems to me that comp.Paste() only work with the clipboard on my system.

The question arises if I am missing something. For example:
Is a Loader node needed for this to work?
Does this only work in Fusion Studio and not the Fusion page in Resolve?
Offline
User avatar

Andrew Hazelden

  • Posts: 596
  • Joined: Sat Dec 06, 2014 12:10 pm
  • Location: West Dover, Nova Scotia, Canada

Re: Is fusion.LoadComp() broken?

PostThu Jan 06, 2022 1:23 pm

How did you create this macro? Likely there is invalid syntax in the Lua table if you are seeing the results you mentioned and the problem wasn't a file path issue. Often this can be caused by a missing comma, at the end of a line in the macro... which can occur if you edited the file by hand in a text editor like "Notepad" that lacks syntax highlighting.

Also, the filepath in your example doesn't have backslashes that are escaped with "\\".

If you aren't using Linux/macOS style slashes then you will likely have to manage escaping the Windows style slashes by hand if you are going to use them. For example to explain where issues can appear with unescaped slashes in a filepath, if you had the letters "n", "r", or "t" as the first digit after the backslash, (without using double slashes), what you typed in will be translated into a C-Code style control character: "\n" = newline, "\r" carriage return, "\t" = tab.

* * *

To further help with troubleshooting, do you have an actual standalone media pool Fusion composite open in the Fusion page, or an Edit page timeline clip loaded as the foreground Fusion page comp?

* * *

I tested Resolve v17.4.3 on Windows 10 and had no issue adding an external macro to the foreground Resolve Fusion page composite I created in the Media Pool. The macro had no Loader nodes or MediaIn nodes present in it, and used the Fusion page's 3D system.

Resolve Studio v17.4.3 on Windows.png
Resolve Studio v17.4.3 on Windows.png (613.81 KiB) Viewed 3988 times



Here is the exact Python code I ran:

Code: Select all
# Stop Loader/Saver node file dialogs from showing
comp.Lock()
 
# Translate a relative PathMap location into a filepath:
macroFilePath = comp.MapPath(r'C:\\ProgramData\\Blackmagic Design\\DaVinci Resolve\Fusion\\Reactor\\Deploy\\Macros\\3D\\CoopersShape3D.setting')
print('[Macro File] ' + macroFilePath)
 
# Read the macro file into a variable
macroContents = bmd.readfile(macroFilePath)
print('[Macro Contents]\n' + str(macroContents))
 
# Add the macro to your foreground comp
comp.Paste(macroContents)

# Resume Loader/Saver node file dialogs from showing
comp.Unlock()


Here is a zipped copy of a macro file I used that you can test.

CoopersShape3D.zip
(11.95 KiB) Downloaded 155 times


Note: BMD's forum system will only allow a macro to be attached to a message posting if it is archived as a zip. You will need to unzip the file on your desktop to leave you with a "CoopersShape3D.setring" file in order to use it inside of Resolve, on your system.
Reactor.lua:933: attempt to index global 'ui' (a nil value)
Offline

DavidSE

  • Posts: 11
  • Joined: Wed Mar 03, 2021 6:13 pm
  • Real Name: David Rehnstrom

Re: Is fusion.LoadComp() broken?

PostThu Jan 06, 2022 7:53 pm

Andrew Hazelden wrote:How did you create this macro? Likely there is invalid syntax in the Lua table if you are seeing the results you mentioned and the problem wasn't a file path issue. Often this can be caused by a missing comma, at the end of a line in the macro... which can occur if you edited the file by hand in a text editor like "Notepad" that lacks syntax highlighting.

I right clicked on the node and --> settings --> save as.
Dont think it is a problem with the lua table since I can ctrl+v it in to the comp

Andrew Hazelden wrote:Also, the filepath in your example doesn't have backslashes that are escaped with "\\".

If you aren't using Linux/macOS style slashes then you will likely have to manage escaping the Windows style slashes by hand if you are going to use them. For example to explain where issues can appear with unescaped slashes in a filepath, if you had the letters "n", "r", or "t" as the first digit after the backslash, (without using double slashes), what you typed in will be translated into a C-Code style control character: "\n" = newline, "\r" carriage return, "\t" = tab.


I have never needed to escape backlashes in a raw string path before and as you can see in the workaround below the raw string works fine. Maybe there is a difference between python 2 and 3 or some special need in Resolve. All tho I am new to windows so I will explore this further but double slash did not solve the problems sadly.


Andrew Hazelden wrote:To further help with troubleshooting, do you have an actual standalone media pool Fusion composite open in the Fusion page, or an Edit page timeline clip loaded as the foreground Fusion page comp?


I do not have a clue. I will provide a picture trying to run the code insted
Capture.PNG
Capture.PNG (103.58 KiB) Viewed 3944 times


Andrew Hazelden wrote:I tested Resolve v17.4.3 on Windows 10 and had no issue adding an external macro to the foreground Resolve Fusion page composite I created in the Media Pool. The macro had no Loader nodes or MediaIn nodes present in it, and used the Fusion page's 3D system.

Here is the exact Python code I ran:

Code: Select all
# Stop Loader/Saver node file dialogs from showing
comp.Lock()
 
# Translate a relative PathMap location into a filepath:
macroFilePath = comp.MapPath(r'C:\\ProgramData\\Blackmagic Design\\DaVinci Resolve\Fusion\\Reactor\\Deploy\\Macros\\3D\\CoopersShape3D.setting')
print('[Macro File] ' + macroFilePath)
 
# Read the macro file into a variable
macroContents = bmd.readfile(macroFilePath)
print('[Macro Contents]\n' + str(macroContents))
 
# Add the macro to your foreground comp
comp.Paste(macroContents)

# Resume Loader/Saver node file dialogs from showing
comp.Unlock()


Here is a zipped copy of a macro file I used that you can test.

The attachment CoopersShape3D.zip is no longer available


In the image above I am running this exact code only changing the file path but escaping the slash this time. Dont know any thing about the 3D system and if I remember correctly there are some limitations on 3D in Resolve Free so maybe that is why this fails. All tho a simple text node also fails in the same way.

To me it seems that we have done this in the same way with the exception of the python version. So I guess uninstall python 3 and install v.2 just got on the todo list.

***

I made a workaround with pyperclip, all tho I would like to be able to use the BMD built ins instead. I dont think it will shead any light on the problem but I will post it any way if someone else have the same issue and needs a workaround.

Code: Select all
import pyperclip

# Absolute filepath to the macro
macroFilePath = r'C:\Users\david\DVR/Text1.setting'
print('[Macro File] ' + macroFilePath)

# Read the macro file into a variable
macroContents = (open(macroFilePath)).read()

# Copy the macro content to the os clipboard
pyperclip.copy(macroContents)

# Print the content of the os clipboard
print('[macro contents]\n', pyperclip.waitForPaste())

# Add the macro to your foreground comp
comp.Paste()

# Empty the clipboard
pyperclip.copy('')


Note: I tried to comment to the best of my ability but being new to DVR I might describe this completely wrong. Also you probably do not want to print the content of the clipboard.

And the result
Capture2.PNG
Capture2.PNG (165.5 KiB) Viewed 3944 times
Offline

DavidSE

  • Posts: 11
  • Joined: Wed Mar 03, 2021 6:13 pm
  • Real Name: David Rehnstrom

Re: Is bmd.readfile() broken in Python 3?

PostSun Jan 09, 2022 3:42 pm

I changed the subject from "Is fusion.LoadComp() broken?" to "Is bmd.readfile() broken in Python 3?" tho it reflects the issue better to what have been discussed so far. All tho to me it seems like a lot is broken in Python 3. Here is why.

Let us start with an TextPlus node and change the name from Text1 to my_text, so there will not be any confusion later when pasting it back in to the nodes window, and save the node as my_text.setting

my_text.setting
Code: Select all
{
   Tools = ordered() {
      my_text = TextPlus {
         CtrlWZoom = false,
         NameSet = true,
         Inputs = {
            GlobalOut = Input { Value = 119, },
            Width = Input { Value = 1920, },
            Height = Input { Value = 1080, },
            UseFrameFormatSettings = Input { Value = 1, },
            ["Gamut.SLogVersion"] = Input { Value = FuID { "SLog2" }, },
            Font = Input { Value = "Open Sans", },
            Style = Input { Value = "Bold", },
            Size = Input { Value = 0.122, },
            VerticalJustificationNew = Input { Value = 3, },
            HorizontalJustificationNew = Input { Value = 3, },
         },
         ViewInfo = OperatorInfo { Pos = { 782.94, 79.0684 } },
      }
   },
   ActiveTool = "my_text"
}



Changing
Tools = ordered() {
to
Tools = OrderedDict() {
in the .setting file. Now it gets imported to the nodes window with the code Andrew previously provided.

So now I thougt that I can read the file with pythons built in tool open() and than use bmd.readstring() instead so I do not have to fiddle with the .setting file every time. Passing a string, any string a valid node or even just a single letter, to readstring() makes Resolve quit immediately. So now I can add readstring() to the list of things that make Resolve crash, like accessing a key frame with the [n_frame] notation.

So I headed over to lua. Doing everything the same way both readfile() and readstring() behaved as expected. No need to change ordered to OrderedDict or crashing applications.

Therefor I suspect that BMD do not maintain the python 3 scripting capabilities.

On one hand it does not feel surprising that things are a little broken here and there when the supported python 3 version is so old that there are not even any security updates to it any more. On the other hand I have to complain that I have spent sooo much time trying to solve issues related to scripting in python 3 and if there are so that BMD do not maintain that capability maybe some sort of information about that would be in order.

Or maybe it is just on my machine. Any one here using python 3 that can confirm or refute this?
Offline

inregu

  • Posts: 1
  • Joined: Sun Dec 10, 2023 10:13 pm
  • Location: France
  • Real Name: Philippe Bouvier

Re: Is bmd.readfile() broken?

PostTue Jan 30, 2024 4:00 pm

Andrew Hazelden wrote:I tested Resolve v17.4.3 on Windows 10 and had no issue adding an external macro to the foreground Resolve Fusion page composite I created in the Media Pool. The macro had no Loader nodes or MediaIn nodes present in it, and used the Fusion page's 3D system.



Hello everyone,

in his post Andrew Hazelden is sharing a LoadMacro.py script.
--
comp.Lock()
macroFilePath = comp.MapPath(r'C:\\ProgramData\\BlackmagicDesign\\CoopersShape3D.setting')
print('[Macro File] ' + macroFilePath)
macroContents = bmd.readfile(macroFilePath)
print('[Macro Contents]\n' + str(macroContents))a
comp.Paste(macroContents)
comp.Unlock()

--

When I run it in the console, it runs as expected.
His file CoopersShape3D.setting is read fine and pasted in the active fusion page as he described it.

BUT

I created a Python program and included the same portion of the text.
The execution is fine until the line below is executed
macroContents = bmd.readfile(macroFilePath)
many error messages appear
---

Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
SystemError: null argument to internal routine
Traceback (most recent call last):
File "<nofile>", line 1, in <module>
NameError: name 'OrderedDict' is not defined
SystemError: null argument to internal routine
SystemError: null argument to internal routine


---
As if the file CoopersShape3D.setting was corrupted (which cannot be the case)
And I have the same issue with another xxx.setting file that I created from DVR app.

My config:
Config DaVinci Resolve Studio license 18.6.4
Python 3.6.8 on Windows


Any thoughts or experience on this?
Thanks
All the best
Philippe
Config DaVinci Resolve Studio license 18.6.4
Python 3.6.8 on Windows 11
NVIDIA 4500
Offline

ThomasOderud

  • Posts: 1
  • Joined: Tue Sep 24, 2024 8:13 am
  • Real Name: Thomas Øderud

Re: Is bmd.readfile() broken in Python 3?

PostTue Sep 24, 2024 8:14 am

I got the same error, but changing the encoding on the .settings-file to UTF8 BOM made i work.
Offline

LeonhardRender

  • Posts: 100
  • Joined: Thu Feb 09, 2023 7:23 pm
  • Real Name: Leonhard Scarlet

Re: Is bmd.readfile() broken in Python 3?

PostThu Nov 14, 2024 2:35 am

Hi, I tried to LoadComp with according to the forum (VFXPedia) and the manual, but it didn't work.

When trying to load the comp, nothing is done, nor does it bring up any error.
I can call Resolve and Fusion normally, and the path is correct. I tried a Python and Lua version.

Python version
Code: Select all
composition = fusion.LoadComp("C:\\Users\\myuser\\Downloads\\mycomp.comp")
composition.Close()


Lua version
Code: Select all
composition = fusion:LoadComp("C:\\Users\\myuser\\Downloads\\mycomp.comp")
composition:Close()


Is LoadComp still functional?
Offline
User avatar

daniel.koch

Blackmagic Design

  • Posts: 162
  • Joined: Wed Apr 15, 2015 5:54 am

Re: Is bmd.readfile() broken in Python 3?

PostThu Nov 14, 2024 6:12 am

This works as expected in Fusion Studio, but in Resolve it behaves a little differently. The comp is still loaded, but in the background; it's usable but not visible without a corresponding timeline or media pool object.

If you want to interact with the comp in Resolve's UI then you'll need to first get a TimelineItem then call ImportFusionComp() from that.

Return to Fusion

Who is online

Users browsing this forum: No registered users and 25 guests