2
$\begingroup$

I am running a python script that does the following things:

  1. read data from csv file and stores them in two variables
  2. runs a function that creates bezier curve with a geometry nodes setup and changes the input sockets of the geo nodes to the values of the two variables stored in the csv.

I get the following error message:

property type does not match input socket "(# Radial Blades)"

enter image description here

This is the code that reads from the csv and executes the function that creates the geo nodes setup and changes the value to the values in the csv.


if __name__ == "__main__":
    blender_input_data = r'C:\Users\Yanni\PycharmProjects\Project_Thesis_\Data\Blender\blender_input_data.csv'

    with open(blender_input_data) as f:
        # Create csv reader object
        blender_input_data_reader_obj = csv.reader(f)
        # Iterate through every row in the csv reader object
        for row in blender_input_data_reader_obj:
            number_of_radial_blades, blades_geometry= row
            #print(number_of_radial_blades, blades_geometry)

    #number_of_radial_blades = 10
    #blades_geometry = 0.1
    create_Pipe_with_Blades(number_of_radial_blades, blades_geometry)

The script works when i give the variables a value in the script manually. It also prints correctly from the csv.

number_of_radial_blades = 10
    blades_geometry = 0.1
    create_Pipe_with_Blades(number_of_radial_blades, blades_geometry)

The function that is called by main:

import bpy
import csv



def create_Pipe_with_Blades(number_of_radial_blades, blades_geometry):
    def trigger_update():
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.object.mode_set(mode='OBJECT')

    # select and del all object
    bpy.ops.object.select_all(action = "SELECT")
    bpy.ops.object.delete(use_global=True, confirm=False)

    # Create Bezier Curve
    bpy.ops.curve.primitive_bezier_curve_add(radius=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

    # Define the active object
    obj = bpy.context.active_object

    # Add geometry nodes modifier
    geometry_nodes = obj.modifiers.new("Pipe_with_Blades", "NODES")
    geometry_nodes.node_group = bpy.data.node_groups['Pipe_with_Blades']


    # Set the radius of the cylinder
    #geometry_nodes["Input_2"] = 1

    # Set the Pipe Outer Radius
    geometry_nodes["Input_6"] = 0.3

    # Set the number of Axial Blades
    geometry_nodes["Input_3"] = 5

    # Set the number of Radial Blades
    geometry_nodes["Input_4"] = number_of_radial_blades


    # Change geometry of the blades
    # a1 - Base of the blades
    geometry_nodes["Input_5"] = blades_geometry


    # b1
    geometry_nodes["Input_7"] = 1
    # a2
    geometry_nodes["Input_8"] = 1
    # b2
    geometry_nodes["Input_9"] = 1


    trigger_update()


    # Convert to Mesh, essentially applying the modifier
    bpy.ops.object.convert(target='MESH')

    # Add a subdivision modifier
    bpy.ops.object.modifier_add(type='SUBSURF')
    # Set the subdivision modifier level to 1
    bpy.context.object.modifiers["Subdivision"].render_levels = 1

    # Save the file
    bpy.ops.wm.save_mainfile()

    # Change working directory to project directory
    save_path = (r'C:\Users\Yanni\PycharmProjects\Project_Thesis_\Data\stl\pipe_with_blades.stl')


    # Export the stl
    bpy.ops.export_mesh.stl(filepath = save_path, check_existing=True, ascii=False, use_mesh_modifiers=True)


The blend.file contains the geometry nodes "Pipe_with_Blades" that i use.

$\endgroup$
3
  • $\begingroup$ Hello ! Since they come from a text file, the numbers are most likely interpreted as strings and that throws off the inputs of the GN modifier. Try casting them with number_of_radial_blades = int(number_of_radial_blades ) and blades_geometry= float(blades_geometry) $\endgroup$
    – Gorgious
    Jan 12 at 7:15
  • $\begingroup$ @Gorgious I found the problem. If you assign native float values to class float instances which are the types of those Input_X sockets, it will throw an exception which is odd because python supposedly knows how to coerce cast convert them into float objects so you have to explictly cast even the float objects = float(0.3) lol which is really odd. $\endgroup$ Jan 12 at 8:27
  • $\begingroup$ Oh I tried again, its only the int values that cannot implicitly be coerced into float. like geometry_nodes["Input_7"] = 1 it should be written as geometry_nodes["Input_7"] = 1.0 $\endgroup$ Jan 12 at 8:35

1 Answer 1

4
$\begingroup$

Supposedly if you assign a native int value to a Python float object, Python will implicitly convert the native int to a Python float class. This is known as type coercion and is a common feature of many programming languages. But for some reason Blender python cannot implicitly convert your native int value to a float object value in your case. The type in geometry_nodes["Input_7"] for example is class float and any instance of this class when assigned a native int value should have automatically been coerced into float class object. To remedy this quirk, just explicitly cast your values as float or use decimal notation like 1.0 instead of 1. Here's the complete working script:

import bpy
import csv

def create_Pipe_with_Blades(number_of_radial_blades, blades_geometry):
    def trigger_update():
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.object.mode_set(mode='OBJECT')

    # select and del all object
    bpy.ops.object.select_all(action = "SELECT")
    bpy.ops.object.delete(use_global=True, confirm=False)

    # Create Bezier Curve
    bpy.ops.curve.primitive_bezier_curve_add(radius=1, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

    # Define the active object
    obj = bpy.context.active_object

    # Add geometry nodes modifier
    geometry_nodes = obj.modifiers.new("Pipe_with_Blades", "NODES")
    geometry_nodes.node_group = bpy.data.node_groups['Pipe_with_Blades']

    # Set the radius of the cylinder
    #geometry_nodes["Input_2"] = 1

    # Set the Pipe Outer Radius
    geometry_nodes["Input_6"] = 0.3

    # Set the number of Axial Blades
    geometry_nodes["Input_3"] = 5

    # Set the number of Radial Blades
    geometry_nodes["Input_4"] = int(number_of_radial_blades)

    # Change geometry of the blades
    # a1 - Base of the blades
    geometry_nodes["Input_5"] = float(blades_geometry)

    # b1
    geometry_nodes["Input_7"] = 1.0 # or float(1)
    # a2
    geometry_nodes["Input_8"] = 1.0 # or float(1)
    # b2
    geometry_nodes["Input_9"] = 1.0 # or float(1)

    trigger_update()

    # Convert to Mesh, essentially applying the modifier
    bpy.ops.object.convert(target='MESH')

    # Add a subdivision modifier
    bpy.ops.object.modifier_add(type='SUBSURF')
    # Set the subdivision modifier level to 1
    bpy.context.object.modifiers["Subdivision"].render_levels = 1

    # Save the file
    bpy.ops.wm.save_mainfile()

    # Change working directory to project directory
    save_path = (r'C:\Users\Yanni\PycharmProjects\Project_Thesis_\Data\stl\pipe_with_blades.stl')

    # Export the stl
    bpy.ops.export_mesh.stl(filepath = save_path, check_existing=True, ascii=False, use_mesh_modifiers=True)

# number_of_radial_blades = sys.argv[1]
# blades_geometry = sys.argv[2]
# create_Pipe_with_Blades(number_of_radial_blades, blades_geometry)

if __name__ == "__main__":
    blender_input_data = r'C:\Users\Yanni\PycharmProjects\Project_Thesis_\Data\Blender\blender_input_data.csv'

    with open(blender_input_data) as f:
        # Create csv reader object
        blender_input_data_reader_obj = csv.reader(f)
        # Iterate through every row in the csv reader object
        for row in blender_input_data_reader_obj:
            number_of_radial_blades, blades_geometry= row
            #print(number_of_radial_blades, blades_geometry)

    number_of_radial_blades = 10
    blades_geometry = 0.1
    create_Pipe_with_Blades(number_of_radial_blades, blades_geometry)

It's odd I know but if anyone can explain as to why Blender python behaves like this with geometry nodes class float sockets in this scenario, please feel free to update this answer or post your own.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .