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")