List woes and my failed and successful attempts to rectify them

Hi all - I have a couple of instances of list configurations that I was hoping I could run by you clever lot.

One of them I solved myself using Python but wanted to see if there was a more succinct way that I could have done it or by using Dynamo nodes as I was struggling!

The other is unresolved and I’m pretty certain it is a levels issue but I’ve tried all of the combinations that make sense to me to little avail.

I’ll start with the latter:

I need to do a list replace with the following.

The curves coming out of the Curve.ExtendEnd need to replace the lines in the Orange groups at the specified indices coming out of the List.IndexOf.

I need the curve at index 0 in list 0 to replace the line at index 1 in list 0 of the slab perimeter curves. I then need the curve at index 1 of list 0 to replace the line at index 3 in list 0 of the slab perimeter curves.

Then to move on to the next list and do the same in the same structure.

I am having issues doing this and do not know if I need to chop my lists or if I just need to adjust the levels. Any ideas?

The second list issue that I have solved using Python is the following.

Given a list of sublists that contains the bounding box extents of all walls grouped by level, to do an intersection test with every item in a similar list of sublists. But, rather than bounding boxes of walls, it is an intersection test with bounding boxes of cavity barriers placed on the level above.

An intersection test is done between each cavity barrier and every wall on the level below the cavity barrier. If any of the wall bounding boxes intersects a cavity barrier bounding box, the relative wall is to be appended to a list. Once all the walls at the level have been checked against the first cavity barrier in the sublist, all of the walls in the temporary list are appended to a higher-order list and the next cavity barrier in the list is checked against all the walls again.
Once all the cavity barriers from the first level have been checked, the script moves onto the next sublist which represents the cavity barriers on the level above and the process is repeated.

These lists are passed on to the Cut Geometry node which is why I need like for like wall and cutting element (cavity barrier) lists.

The end result does and should look like this:
Walls Grouped
Cavity Barriers Grouped

The input lists look like this:

The code is here:

import clr
from Autodesk.DesignScript.Geometry import *
from DSCore import *

BB_cavity_barriers = IN[0] # Bounding boxes of all cavity barriers
grouped_cavBs = IN[1] # Cavity barriers in lists /grouped  by level
grouped_walls = IN[2] # Walls in lists /grouped  by level
BB_walls = IN[3] # Bounding boxes of all walls

#Function that, given bounding boxes of walls & cavity barriers, will check which cav B's 
#are in which walls and group them accordingly. A corresponding list of cavity barriers 
#with the same list structure is also created so that the cutting node in Dynamo 
#has a like for like host / cutting element. 
def intersection_test (BB_cavity_barrier_set, BB_wall_set, wall_set, CB_set):
	sorted_walls = [] # List for walls once grouped 
	sorted_CavBs = [] # List for cavity barriers once grouped
	for i, barrier in enumerate(BB_cavity_barrier_set): # for each barrier
		# intermediate list required so if multiple walls intersect 1 CB they are appended as a group
		intermediate_wall_list = [] 
		intermediate_CB_list = []
		for index, wall in enumerate(BB_wall_set): # for each wall against each barrier
			if BoundingBox.Intersects(barrier, wall): # check intersection 
				intermediate_wall_list.append(wall_set[index]) # if intersects append to the intermediate list
		#once each wall in the set has been checked against the 1 CB the intersecting walls are appended to the sorted list as a group.
		#if more than 1 wall intersects the CB then the CB is cycled by the number of repititions required to create the like for like list. 
		if len(intermediate_wall_list)>1:
			sorted_CavBs.append([CB_set[i]]) # if just 1 intersection then only 1 CB appended
	return sorted_walls, sorted_CavBs

grouped_by_cavB_walls = [] #empty list

for index, wall_group in enumerate(grouped_walls): #run the function on the elements level by level and append the results
	grouped_by_cavB_walls.append(intersection_test(BB_cavity_barriers[index], BB_walls[index], wall_group, grouped_cavBs[index]))

OUT = grouped_by_cavB_walls

I would appreciate any help anyone can give on either of these (the one I haven’t yet solved is; unsurprisingly, the more important of the two.


First Problem: The out of the box node does not replace items recursively. You will get a new list for each item being replaced. There are custom nodes that will replace multiple items recursively, or you can do it with python pretty easily. With python you can just define the new items in the list by their index.

Second Problem: Python is probably going to be the easier solution anyway. The more list levels you have the more likely that each level is controlled separately, making it impossible for a single node to work the way you’d expect. You can always duplicate elements and lists so that everything has a 1-to-1 ratio of inputs, but that isn’t always realistic.

1 Like

ind1 = 0..List.Count(a<1>)-1;
ind2 = List.SetDifference(ind1,b);
lst1 = List.GetItemAtIndex(a<1>,ind2<1>);
lst2 = List.Flatten(List.Transpose([lst1,c])<1>,-1);
lst3 = List.Flatten(List.Transpose([ind2,b])<1>,-1);
lst4 = List.SortByKey(lst2<1>,lst3<1>)["sortedList"];

replaceMultiple.dyn (28.4 KB)


Cheers for the response, Nick.

Yea finding manipulating custom list structures a lot easier to do with Python than any OOTB nodes. Certainly looks less messy at least haha. Just wanted to know if there was anything I was missing somewhere.

Thanks a lot for this Vikram - The transposition and then sorting by key is a real beauty.

Have implemented into my script.

1 Like