It only picks up 14 rooms. All (or at least 90%) rooms are bounded and placed, everything looks good in the linked model. I am really not sure what to make of this.
Does anybody have any ideas or directions I can look into?
Is this potentially signifying that the additional rooms might actually be in a separate link that is link via Attachment into the Arch model? Essentially nesting it?
But I just realized something⌠This Arch file is actually empty, and all the other files have been linked in to the Arch model. I am presuming that this process I am using cant work at that level of nesting?
Can I reach in from the host file into the Arch model and identify the linked files in the Arch model, then reach into those files and extract the room data? All from the host file?
Anything is possible, just a question of how much custom code or scripting you have to do. See if you can get the link instances from the link, and then get the rooms from there as a start. Note that location data will likely be way off as youâll need to transform the nested link to the linkâs coordinates and then into the active modelâs coordinates.
So as a start, the model that contains the rooms is linked into the Arch model as an attachment. A separate model contains the shell of the building. So the model that contains the rooms, as well as the shell model, work together to enclose the rooms.
Now in the host file, I have identified the link that contains the rooms, but when I feed it into the node I get the following error:
example of code Python (IronPython3 or PythonNet3)
import clr
import sys
import System
from System import Array
from System.Collections.Generic import List, IList, Dictionary, HashSet
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
host_link = UnwrapElement(IN[0])
dict_Rooms_links = FilteredElementCollector(doc).OfClass(RevitLinkInstance)\
.Where(System.Func[DB.Element, System.Boolean](lambda e : doc.GetElement(e.GetTypeId()).GetParentId() == host_link.GetTypeId()))\
.ToDictionary[System.Object, System.Object, System.Object](
System.Func[System.Object, System.Object](lambda i : i.Name.replace(":","-")),
System.Func[System.Object, System.Object](lambda i : FilteredElementCollector(i.GetLinkDocument())\
.OfCategory(BuiltInCategory.OST_Rooms)\
.ToElements() )
)
OUT = dict_Rooms_links
This really is spot on, I can grab the rooms from the nested links using this code. Appreciate your assistance here greatly!
Do you have any genuine tips on how to start getting acquainted and familiar with writing code for the AEC space and Revit specifically? As someone who has no formal programming training at all, I do find it quite overwhelming at timesâŚ
I have gotten started several times but struggle to keep up momentum as it just feels like no results are coming from the effort.
I have gone through tutorials, looked at Revit API Docs, gone through the SDK, tried python, tried C#⌠I just donât really know where to start at a practical level.
Any advice or personal experience would be highly appreciated.
Thanks Jacob, you have been guiding me with suggestions on this platform for almost a decade and I appreciate your insights.
I wonder if you could weigh in on my reply to @c.poupin as well?
Just looking for some practical advice or tips on how to get started with coding. Given that Revit is the tool of choice in this instance, is Python better or is C# the way to go?
I know there are tons of resources out there on how to get started, but personal experience always seems to give better insights.
Riffing on @c.poupinâs code, hereâs a recursive function that will scrape every room it can find.
from pathlib import Path
import clr
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
def get_rooms(doc):
yield from FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms)
def get_all_rooms(doc, rooms=dict()):
path = Path(doc.PathName)
if path.stem not in rooms:
rooms.setdefault(path.stem, []).append(get_rooms(doc))
# Explore links
links = FilteredElementCollector(doc).OfClass(RevitLinkInstance)
for link in links:
link_doc = link.GetLinkDocument()
if link_doc:
rooms = get_all_rooms(link_doc, rooms)
return rooms
doc = DocumentManager.Instance.CurrentDBDocument
OUT = get_all_rooms(doc)
Edit: The above code will only scrape the first instance of a document
Interestingly, multiple instances of the same nested file with rooms returns identical rooms
This is a question as old as the computer really⌠Itâs likely a billion dollar industry at this point, and yet still unsolved. The reason is that âwhat is bestâ will vary wildly by the variables at play:
Some people learn better in one way rather than another
What was a best practice today can become a worst practice by Monday
What resources are available changes hourly, with things spinning up and down overnight
What was current quickly becomes outdated as the technology changes
So while I canât give a âfoolproofâ path, I can give some advice and a possible path based on the path I have taken and my mood today.
The advice:
Donât get hung up on âwhichâ language to learn; they all stink for one reason or another. Instead focus on the concepts.
Donât try to boil the ocean; start with small parts and scale up.
Failures are victories if you learn something. If you arenât going to learn something then youâre likely on the wrong project.
Aim to teach others not use the tool, even if you arenât going to do any teaching. If you can figure out how to teach it youâve actually mastered it.
There is a âgood enoughâ point and that is often earlier than you think. Donât let perfection stop you from moving onto the next part.
Use tutorials teach concepts and processes, not to get an outcome.
My path:
Start with Dynamo nodes, as they are easy.
Expand into design script, making heavy use of ânode to codeâ and experiment with combining functions into one line statements.
Learn the basics of Python - this happens outside of Dynamo.
Learn Python in Dynamo for basic compute functions and Dynamo automation (not Revit stuff yet).
Introduce the Revit or Civil 3D or AutoCAD API into the Python mix.
Learn the basics of C# - again outside of Dynamo.
Learn zero touch development using C# in visual studio.
Learn node model development using C# in visual studio.
Learn standalone app development using C#.
Learn the basics of web development in JavaScript.
Learn the Autodesk Platform Services to automate without asking anyone to open a tool or hit a button.