Rooms not picking up from linked file

Good morning everyone,

Just looking for some advice here as to why majority of the rooms in the linked file are not getting picked up?

I have a total of 330 rooms, all contained in a single linked Architectural model.

When I run the following process:

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?

Thanks so much.
Mitch

works fine for me.

Try this code and see if there is any discrepancy

import clr

clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *

link_doc = UnwrapElement(IN[0]).GetLinkDocument()

OUT = (
    FilteredElementCollector(link_doc)
    .OfCategory(BuiltInCategory.OST_Rooms)
    .ToElements()
)

Hi Mike,

Using the Python code I get the same result.

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?

the differences!

Do you only have one instance of that link, or could there be many?

1 Like

It is just one instance in this case.

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?

No - but you’ll have to pass in the linked documents that are in the arch model and pull data from those instead of the arch model itself.

1 Like

Is it possible to do that from the host file?

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.

1 Like

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:

I am not sure if I have assembled everything correctly, but this is how I have understood it so far.

I am not sure what that error message means and what it is asking for, any ideas?

Likely the BiMorph package isn’t built for this, or something else in the file is preventing access.

Why are you gathering these rooms?

I need to collect certain room data and write the parameter information from the room, to signage that is placed in/near the room.

1 Like

Here is a workaround for obtaining child RevitLinkInstance rooms using the GetParentId() method.GetParentId()

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
4 Likes

So the ‘forward progress’ way is likely to directly link the attached rvts into your file. You can then quarry those individually.

The smart way is likely to script something yourself. @c.poupin gave you a good start there.

1 Like

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

3 Likes

you can find some infos in this topic

1 Like

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:

  1. Don’t get hung up on “which” language to learn; they all stink for one reason or another. Instead focus on the concepts.
  2. Don’t try to boil the ocean; start with small parts and scale up.
  3. Failures are victories if you learn something. If you aren’t going to learn something then you’re likely on the wrong project.
  4. 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.
  5. 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.
  6. Use tutorials teach concepts and processes, not to get an outcome.

My path:

  1. Start with Dynamo nodes, as they are easy.
  2. Expand into design script, making heavy use of ‘node to code’ and experiment with combining functions into one line statements.
  3. Learn the basics of Python - this happens outside of Dynamo.
  4. Learn Python in Dynamo for basic compute functions and Dynamo automation (not Revit stuff yet).
  5. Introduce the Revit or Civil 3D or AutoCAD API into the Python mix.
  6. Learn the basics of C# - again outside of Dynamo.
  7. Learn zero touch development using C# in visual studio.
  8. Learn node model development using C# in visual studio.
  9. Learn standalone app development using C#.
  10. Learn the basics of web development in JavaScript.
  11. Learn the Autodesk Platform Services to automate without asking anyone to open a tool or hit a button.
  12. Retire to the Swedish countryside.
3 Likes