# Batch Python - Create Node and Find Space for it

**URL:** <https://forum.logik.tv/t/batch-python-create-node-and-find-space-for-it/11478>\
**Category:** Python\
**Tags:** batch\
**Created:** [September 27, 2024, 1:19pm UTC](https://forum.logik.tv/t/batch-python-create-node-and-find-space-for-it/11478 "2024-09-27T13:19:20Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![john-geehreng](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.logik.tv/john-geehreng/32/7195_2.png) [@john-geehreng](https://forum.logik.tv/u/john-geehreng)\
**Post date:** [September 27, 2024, 1:19pm UTC](https://forum.logik.tv/t/batch-python-create-node-and-find-space-for-it/11478/1 "2024-09-27T13:19:21Z")

</div>

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:

```auto
# 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")

```
