Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added generate mindmap in Screenwriter #7

Open
tin2tin opened this issue Apr 26, 2023 · 10 comments
Open

Added generate mindmap in Screenwriter #7

tin2tin opened this issue Apr 26, 2023 · 10 comments

Comments

@tin2tin
Copy link
Contributor

tin2tin commented Apr 26, 2023

Hi,
I added generation of screenplay mindmaps(very early steps) to the Blender Screenwriter add-on, but only if your add-on is installed: https://github.com/tin2tin/Blender_Screenwriter

Loads of stuff I don't know about when it comes to nodes ex. how to make links and how to return the node intent in link order to Screenwriter.

Blender_.C__Users_45239_Documents_Blender.Projekter_Add-ons_Mural_send_to_mural_01.blend.2023-04-26.17-43-45.mp4
@tin2tin
Copy link
Contributor Author

tin2tin commented Apr 26, 2023

Hmm, I'll have to ask for some help. Do you have any idea why I can't connect the sockets of the Mindmap addon like this:

                            # create links between nodes
                            for i in range(nodes_cnt-1):
                                tree.links.new(nodes[i].outputs[0], nodes[i+1].inputs[0])

@SpectralVectors
Copy link
Owner

SpectralVectors commented Apr 26, 2023

Possibly range() does not return a compatible type, I would have thought it would work, but it doesn't.
I got it to work by wrapping the range() in a len(), like this:
for i in range(len(nodes_cnt-1))
which spits out an integer at the end that Blender is happy with.

I hacked together a quick test script, I'll post it below, it will connect every node to the node added after it in the MindMap and print a message to the console when it gets an invalid value. Probably not the best way to handle it, but it should give you something to work from:

import bpy

tree = bpy.data.node_groups['Mind Mapper']
nodes = tree.nodes
count = range(len(nodes))

for i in count:
    try:
        tree.links.new(nodes[i].outputs[0], nodes[i+1].inputs[0])
    except:
        print("Job's Done!")

@SpectralVectors
Copy link
Owner

You can also refer to nodes by name, which might not be that convenient in this case, eg: nodes[0] could also be accessed as nodes['Mindmap'], nodes[1] as nodes['Mindmap.001'] and so on, with Blender's naming convention being: add .001, .002, .003 etc for each additional object.

If you're writing a script you can also refer to them by variable name within the script. I find that this is the most convenient when you want to deal with a lot of nodes, or a lot of complex connections, but to take advantage of that you would want to be creating the nodes from the script as well.

You can check out the approach I took to that in the objects for my GhibliGenerator addon: https://github.com/SpectralVectors/GhibliGenerator/blob/main/Objects/RainPlane.py

@SpectralVectors
Copy link
Owner

I didn't actually watch your video until now, wow that's cool!

@tin2tin
Copy link
Contributor Author

tin2tin commented Apr 26, 2023

Thank you for the code now the links are working. It was this line missing:
tree = bpy.data.node_groups['Mind Mapper']

image

Phew, I'm a complete noob when it comes to coding nodes...

The code is very much wip. I don't know if I can get line breaks to work in the nodes, if not a lot of code can go out:
https://github.com/tin2tin/Blender_Screenwriter/blob/master/operators/mindmap_fountain.py

Do you have any ideas for returning the linked nodes back to text?

@tin2tin
Copy link
Contributor Author

tin2tin commented Apr 26, 2023

ChatGPT came up with this for extracting the texts:

                            nodes = tree.nodes

                            # Initialize the arrays to store the node order and labels
                            node_order = []
                            node_labels = []

                            # Loop through the nodes in the material's node tree
                            for node in nodes:
                                # Check if the node is connected
                                if node.inputs:
                                    # Loop through the inputs of the node
                                    for input in node.inputs:
                                        # Check if the input is connected
                                        if input.is_linked:
                                            # Loop through the links of the input
                                            for link in input.links:
                                                # Add the from_node to the node_order array
                                                node_order.append(link.from_node)
                                                # Add the label of the from_node to the node_labels array
                                                node_labels.append(link.from_node.my_string_prop)

                            # Print the node order and labels
                            print(node_order)
                            print(node_labels)

@SpectralVectors
Copy link
Owner

I think ChatGPT might be complicating things more than it needs to, the following code returns all the node strings in the node order:

import bpy

tree = bpy.data.node_groups['Mind Mapper']
nodes = tree.nodes

for node in nodes:
    print(node.my_string_prop)

If you need them to be in a certain order then you would have to sort them, this will return - Mindmap, Mindmap.001, Mindmap.002 etc.

If you had branching paths then you might need to separate those and run multiple loops, but to just get the label string back you can get it 'top-level' from the node, rather than going through the inputs to collect the values, like usual.

I have another script that scrapes and outputs positions, links and input values from material node trees, I'll post it here whenever I have the chance, in case it helps.

@SpectralVectors
Copy link
Owner

re: line breaks - that was an issue for me, too. Right now the lines are automatically broken at a certain length.
You could possibly add a line break as a character that it checks for to determine where the line should be broken, rather than at a certain line length, but I'm not sure how to do that right now, it was a bit of a hack to even get text to render on multiple lines without using multiple string props!

@tin2tin
Copy link
Contributor Author

tin2tin commented Apr 26, 2023

I wanted it to go through the linked nodes, preferable starting with the one with only an output first and end with the one with only an input. So, the links will determine the order(which means there can only be one link), and then the rest without links should be added afterward.

Btw. could be cool to batch add images for ex. the VSE as nodes too. That's properly doable, too. I have this add-on which can generate Stable Diffusion images, could be cool if you could batch add them to the mindmapper too, so you can throw both text and images around when designing stories.

Maybe the strings could be wrapped after forced line breaks?

Too late here now. Gotta call it a day. Thanks for the help!

@tin2tin
Copy link
Contributor Author

tin2tin commented Apr 27, 2023

Got the returning of node texts working, so it'll work in screenplay format. The sorting is properly not working as good as it should.

Blender_.C__Users_45239_Documents_Blender.Projekter_Add-ons_Mural_send_to_mural_01.blend.2023-04-27.10-58-51.mp4

BTW. if you add this to your mindmap code in line 204, the line spacing will be less:
box = box.column(align=True)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants