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

Input socket types for nodes #341

Open
Surasia opened this issue Jan 23, 2025 · 4 comments
Open

Input socket types for nodes #341

Surasia opened this issue Jan 23, 2025 · 4 comments
Assignees

Comments

@Surasia
Copy link

Surasia commented Jan 23, 2025

Description about the feature

When creating nodes, it doesn't seem possible to use the "default_value" attribute for a NodeSocket, as those are defined for subclasses of NodeSocket such as NodeSocketFloat.

For instance, this code accesses the second input of a math node:

subtract = create_node(self.node_tree.nodes, -400, 1083, ShaderNodeMath) # subtract is of type ShaderNodeMath
subtract.operation = "SUBTRACT" # this works
subtract.inputs[1].default_value = 1.0

This however throws a type error as .default_value may is not defined in the NodeSocket class. It's possible to work around this by overriding the type of the input:

subtract = create_node(self.node_tree.nodes, -400, 1083, ShaderNodeMath)
subtract.operation = "SUBTRACT"
_: NodeSocketFloat = subtract.inputs[1]
_.default_value = 1.0

Unfortunately, the documentation does not seem to specify the types for each input in a node socket, so I'm not sure if an implementation is possible.

Are you willing to contribute about this feature.

Yes, contributing to blender docs to specify input types.

@JonathanPlasse
Copy link
Contributor

JonathanPlasse commented Jan 23, 2025

I would love having this feature.

I think you could do the following to implement this feature.

  1. Find a way to get the inputs type information from the Blender Python console.
  2. Update gen_external_modules_modfile.py to generate mod files with the inputs type information.
  3. Find a way to encode the input type information in Python when you can use both integer or string indexing.

Something like this could work for 3.

class A:
    @overload
    def __getitem__(self, key: Literal[1]) -> Literal["a"]: ...
    @overload
    def __getitem__(self, key: Literal["a"]) -> Literal["a"]: ...
    @overload
    def __getitem__(self, key: Literal[2]) -> Literal["b"]: ...
    @overload
    def __getitem__(self, key: Literal["b"]) -> Literal["b"]: ...
    def __getitem__(self, key: int | str) -> Any: ...

What is describe above do not require a change to the Blender documentation.
There may be push back from the Blender project to do such a huge change to the documentation as it would require modifying the documentation of all nodes.
This could be done in a second time.

You may need to make a PR to Blender to surface the node type information

@nutti, may have more to say on this.

@Surasia
Copy link
Author

Surasia commented Jan 23, 2025

Iterating over the node inputs does return the class of the socket at runtime, will try writing something that should be able to dump that type information into a definition file. Thanks for the tips!

@Surasia
Copy link
Author

Surasia commented Jan 23, 2025

Incredibly embarrassed to have come up with this, but this seems to work?
One issue is that each node type is not initialized when blender launches, so you need to go through the UI to register each. I'm not familiar with how blender's RNA system works so I'm sure there's a much better way.

import bpy

for node in bpy.types.ShaderNode.__subclasses__():
    obj = bpy.context.selected_objects[0].material_slots[0].material.node_tree
    m = obj.nodes.new(node.__name__)
    print("--------------")
    print(m.__class__.__name__)
    print("--------------")
    for i, input in enumerate(m.inputs):
        print(f"[{i}]: {input.__class__.__name__}: {input.name}")

@nutti
Copy link
Owner

nutti commented Jan 25, 2025

@JonathanPlasse

I agree with your idea.
inputs whose data type is NodeInputs is common class used in many nodes.
https://docs.blender.org/api/current/bpy.types.Node.html#bpy.types.Node.inputs
So, generating mod file is a good solution to solve this issue.
But we need to concern about the overhead of applying mod files.

@Surasia
You can look into this issue.
Once you finished the work, please consider to make PR :)

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

No branches or pull requests

3 participants