I need to find all the elements that are the boundaries of the rooms and write down the rooms names into these elements. If one element is the boundary of several rooms, then write down all the rooms names separated by commas.
I can not solve the intermediate task with lists:
@SeanP I am not sure that it would be this easy. Please provide an image of your proposed solution so that we can try it out.
Now my understanding is that @NurlanAdsk wants to create a list of all bounding elements (walls?), and then under each wall list what rooms are bound by this wall.
# Copyright(c) 2018, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net
import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
try:
errorReport = None
output = [[] for i in range(len(IN[0]))]
for index1, i in enumerate(IN[0]):
for index2, j in enumerate(IN[1]):
if i in j:
output[index1].append(IN[2][index2])
except:
# if error occurs anywhere in the process catch it
import traceback
errorReport = traceback.format_exc()
# Assign your output to the OUT variable
if None == errorReport:
OUT = output
else:
OUT = errorReport
Basically the idea is that we first get all of the rooms, and their bounding elements. I flatten the list of bounding elements because one wall can bound multiple rooms, so we want to remove all duplicates. Next, I use a little Python code, to iterate over every unique wall, that we know participates in bounding of at least one room, and add them to a list. The output here basically lists what rooms are bound by each wall.
Thank you for your solution and for the archi+lab package! Great job!
As a result, I need to fill in the rooms information in all the elements that are boundaries, as well as in some categories located in the rooms (crossing them). I will try to use your code for the whole task, I hope I can figure it out
Really interesting code, the ways that you have used enumerates and defined output are new to me. I’ve had a go at trying to understand it, I would be very appreciative if you could comment my interpretation…
# Copyright(c) 2018, Konrad K Sobon
# @arch_laboratory, http://archi-lab.net
# markup by MKA who takes no credit and all the blame
import clr
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
# define inputs
wallsHeader = IN[0]
walls = IN[1]
rooms = IN[2]
rng = []
output = []
try:
errorReport = None
# create a range of length wallsHeader
for WH in range(len(wallsHeader)):
rng = []
#define the structure of the output has having a list length rng
output.append(rng)
for indexWH, WH in enumerate(wallsHeader):
for indexRM, RM in enumerate(rooms):
if WH in RM:
#for the index of wall header, append the wall at index of room
output[indexWH].append(walls[indexRM])
except:
# i added a library call above
# if error occurs anywhere in the process catch it
import traceback
errorReport = traceback.format_exc()
# Assign your output to the OUT variable
if None == errorReport:
OUT = output
else:
OUT = errorReport
Both your for WH in range(len(wallsHeader)):
and his output = [[] for i in range(len...
can be shortened to just output = [[] for i in IN[0]]
as you don’t need the actual element inside the for loop, just the iteration amount, which is the same in either process.
My commenting is just that I can’t understand the concise code and have to make it really obvious… So mine is going to be way longer to break down each step into it’s bits…
Yours is even more elegant than Konrads, therefore even harder for me to understand at least if there’s a range, it helps me know that we’re talking about the length of something…
Sorry, I was just trying to show why range(len()) can be a bit misleading in this situation but I didn’t explain it.
All mine and Konrad’s shortened version is basically boiling down for loops into a single line with a slightly different syntax. It ends up reading like an English sentence and can work for simple if statements as well. But the principle is the same as
for WH in range(len(wallsHeader)):
rng = []
output.append(rng)
Except the final line is output.append([])
My change is that since we do not actually need WH in the output of the for loop, there is no need to do range(len()). A simple for i in wallsHeader would work just as well because we just want it to iterate. So for every time it gets to an item in the list, append [].
There is a “Tool.GetSurroundingElements” from the SteamNodes that gives a list of the desired format, but unfortunately gives the wrong result, because it uses Bounding Box.
@NurlanAdsk just a quick comment. When you ask a question, try not to create new questions later in the post. It confuses people. Also, this post had an answer awarded already, and the fact that you asked yet another question with potentially new answer creates a situation where one user will not be rewarded with an approved answer. Let’s not do that. Start a new post next time.