Batch Python - Create Node and Find Space for it

ChatGPT helped me write a script that finds space for a node, so I thought I’d share it. The following example is the section that creates a paint node, finds space for it, and connects it to the node that was right-clicked:

# Define a function to calculate the distance between two points
def is_within_radius(x1, y1, x2, y2, radius=50):
    distance = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
    return distance <= radius

def add_paint_node(selection):
    current_batch = flame.batch
    current = flame.batch.current_node.get_value()
    current_frame = flame.batch.current_frame

    # Extract the actual values from the PyAttribute objects of the current node
    current_pos_x = current.pos_x.get_value()
    current_pos_y = current.pos_y.get_value()

    # Define the target position to match
    target_pos_x = current_pos_x + 200  # Example target position x
    target_pos_y = current_pos_y - 25   # Example target position y

    # Create and connect new Paint node
    new_paint = flame.batch.create_node("Paint")
    # new_paint.load_node_setup("/opt/Autodesk/shared/python/uppercut/presets/rgb_paint.paint_node")
    
    # Initialize the position for new_paint
    new_paint.pos_x = target_pos_x
    new_paint.pos_y = target_pos_y

    # Variable to track how much to move the node down each time if needed
    move_down_units = 175

    # Continuously check for stacking and move the new node down if needed
    move_needed = True  # Start by assuming movement is needed

    while move_needed:
        move_needed = False  # Reset move_needed before each iteration
        
        # Loop through all nodes and check for stacking, ignoring the current node and the new node's position
        for n in current_batch.nodes:
            # Get the actual values from the PyAttribute objects of each node
            n_pos_x = n.pos_x.get_value()
            n_pos_y = n.pos_y.get_value()

            # Skip checking the current node itself and the new_paint node (ignore their positions)
            if n is current or n is new_paint:
                continue

            # If a node is found within the radius, mark that the new node should move down
            if is_within_radius(n_pos_x, n_pos_y, new_paint.pos_x, new_paint.pos_y):
                new_paint.pos_y -= move_down_units
                move_needed = True  # Mark that another move is needed
                print(f"Overlap detected! Moving node down to: x={new_paint.pos_x}, y={new_paint.pos_y}")
                break  # Exit the for-loop to check again in the next iteration

    print("No more overlapping nodes, final position for new node is:")
    print(f"x={new_paint.pos_x}, y={new_paint.pos_y}")

    # Connect Selection to the Paint Node
    flame.batch.connect_nodes(current, "Default", new_paint, "Front")
6 Likes