door numbering v2.0 for dynamo 0.8.0

First of all, huge thanks to Brian Washburn for taking the original Door Numbering definition and upgrading it to Dynamo 0.8.0 version.  Also, Brian pointed out to me a handful of potential issues that I hope I was able to address here. Overall, his input allowed me to make this definition a more robust solution able to handle a larger variety of conditions. Again, thank you!

Also, huge thanks to Sonya Parton from Grimshaw’s AUS office. Your input about angle/sorting of doors allowed me to make some much needed improvements.

Now, let’s get to it. This workflow is not something that I can just wrap up into custom nodes because most of the stuff that I am doing here is project specific or just my personal preference. Not everyone will want to add a letter suffix to a door number, so I am not going to force it on anyone.

Before I drill down to nuts and bolts of this definition, let’s make sure that everyone has a few things installed:

  1. I am using Archi-lab (Grimshaw) package for most of the custom nodes. Get it from Package Manager
  2. I am using Andreas’ custom node Element.Location from Clockwork for Dynamo 0.7.X package.
  3. This definition was made in Dynamo 0.8.0 so it might be good to have that installed.

There is a few steps worth following when numbering doors:

    1. Number your Rooms first. :-) This definition will number doors based on Room numbers so its quite important.
    2. Make sure that ALL door families have Room Calculation Point enabled. How do you know if you did it or not? Edit the Door family in question and under properties check if Room Calculation is checked on or off.
    3. image01
    4. Create a filter. I always create a filter to exclude doors that I don’t want to include in the numbering process. Why? Example? Sure, for example a wall opening that someone thought would be a good idea to model as a door. I am game with that technique, but then I have to make sure that this pseudo doors are excluded from the schedule/numbering somehow. So I always add, a new Shared Parameter called Schedule Exclude or simply type “Exclude” into Comments for that elements.

I think we are ready now to get started. First let’s get our filters out and ready to go. I usually filter for couple things to make sure that I am getting all of the right doors:



This part should be pretty straight forward. I first filter for all of the doors (Categories = Doors) on a given level (Levels = LEVEL 01). Then I check all of the doors that this returns for whether they were Demolished. If a door was already demolished I don’t want to include it in my numbering sequence so I use List.FilterByBoolMask node to exclude all doors that were Demolished (Phase Demolished node returns a Phase Id, if Phase Id is equal to -1 that means door was not demolished because it doesn’t have a Demolished Phase property).

Ps. Something to look out for when filtering doors by Level. Curtain Wall panels that are doors, will report their level to be the same as the Wall Base Level that is hosting them. That means that if you have a Curtain Wall that spans multiple levels, a door placed on a second level will not necessarily return base level as Level 02 since wall base level is 01. Keep that in mind when working with Doors.


Next up is my “manual” filter that I use to exclude all doors that are not really doors (openings, portals etc). This sequence check if parameter Comments equals to EXCLUDE and removes those doors from the list. So far so good.



This part is a little more involved. What is happening is that I am extracting a FromRoom and ToRoom property from each door. My logic for assigning door numbers is that every door gets a number of the room that it swings into. The exception is that if a door swings into a circulation space then it will get a number of a space that it swings from. Custom Python node in the image above is doing just that. the Second input that has List.Create feeding into it is just listing spaces that I want to apply the reverse logic to (if a door swings into CIRC ). Here’s the code for the custom node:

image05   Once, we have our doors and rooms that they swing into its time to do some work to sort them in a nice clockwise order. In order to sort them I first need to extract a location point from a door. Now, here’s a tricky part: Element.Location node will not always return a location point. One exception is a Door family that was created as a Curtain Wall panel. It’s still a Door, but it doesn’t have the same properties as typical door. The workaround for that is to use the Transform Origin point instead. This has worked well for me. Then all we have to do is re-combine the two lists and then start sorting them by an angle in relation to a Room Location point. Don’t worry about the FamilyInstance.Location node going yellow and throwing an error. It is, supposed to do that for the Curtain Wall doors, and I am using that Null values to re-assembly my list. Let’s make an amendment to what I said about my numbering logic. Now, once we have sorted all of the doors for what room they get assigned to, its time to sort them into an order (clockwise) given that there will be more than one door swinging into the room. Each door will get a suffix (a letter A, B, C, D etc). Doors are sorted in a clockwise order from a Room Location point (intersection of room reference lines or as some call it the room X). image08       Now, we collect Door Location point and create a vector from each Room location point to that. Then using Y Axis as our zero angle we measure out all angles from room location to each door assigned to the room. Now, ordering is based on angle between Y axis and a door. Since Dynamo returns angles that are always less than 90 (it does quad based angle measurement where angle returned is always the smallest angle to that vector). That’s why I have that Angle Adjustment Python node in there to convert all angles into more familiar 360 degree angles in relation to the Room Location Point.      

This creates a list of angle values for all our doors, and we are ready to group them, assign numbers to them and then enjoy some beer time. image07   In this last section we do couple important things. First we Group and order all of the doors by their angle and room number, and then we add a proper suffix before finally writing that information to a door Mark parameter. Here is code for grouping and adding suffix:   

This is it! We are done. I hope this helps everyone get their head around this definition. Here are the files: Download

Support archi-lab on Patreon!


  1. Sol Amour says:

    That’s seriously cool dude. Not only is it a brilliant definition in and of itself, it’s great to understand your thought process and gain an insight into the Python you use. Thanks for posting this.

  2. kulkul says:

    Thanks Konrad,

    I am not able to Run. I am getting errors. Custom node definition not loaded. How do i load Custom node definitions?

  3. Sylvester Knudsen says:

    This is really great! Thanks for sharing.

    I was wondering if there was a way to add “_” in front of the suffix, so my suffix would be “10_A”?

  4. Uaifestival says:

    Great code,
    even If I am not using right now, it lets me understand more about the Dynamo and Revit interaction!
    I wish you could write something more about the views problems!
    I used yesterday fr the first time the awesome node that list all the views in a file by the Grimshaw package.
    Now I am wondering if the boundingbox is the same concept for the PerspectiveView and the AxonometricView (isomertric)?

  5. Rory MacTague says:


    nice script and many thanks for sharing. I’m trying to find the Transform Origin node, but it doesnt seem to be in my version of Dynamo 8.1.1483.

    What is that and what does it do? I assume its some kind of get the actual location of the door in coordinates relative to the coordinate system.

    Where can I fin that node? Sorry for the noob level question


    • This is a very valid question. Something happened to it when people were updating their Dynamo version to the latest stable. Can you just uninstall all previous versions and install it fresh? Then go to package manager and install archi-lab package and it should be there.
      What it does? It does just what you described. Get’s an origin point of that door family in its local coordinate system. That origin is usually the same as Door Location, but it addresses the issue of Curtain Wall doors not returning a location property.

  6. Shady says:

    Nice Script, i wanted to use it for a project, since i m learning Dynamo i decided to follow your steps. forsome reason Get Element Location comes back to 0s. which messes up with the rest of the script. Any ideas of how to fix it?

    • if you can give me more than “it doesn’t work” then i will try to help. please post an image of an error and nodes that cause the error. Both inputs and outputs are important to understand what is causing the issue. The best, however, will always be to post a sample file. This will allow me to hopefully re-create the error and then be able to address it faster.

  7. IV says:


    • Mhmmm, all caps? Mhmmmm, many errors. Mhmmmm, I really need to try and contain myself from being a massive dick to you right now.


      • Iv says:

        I think you are way past that at this point lol. But if you have any thoughts on how to make it work I would really appreciate it friend.


        • you mean that I am already a massive dick to you and my response or lack of it will not change your mind. i guess I have that effect on people. as a matter of fact, I am pretty busy. i will not be able to help you with this. sorry.

      • Iv says:

        Well I didn’t see the first comment you left. I will do that tomorrow but I am using revit 2015 with Dynamo 0.9. I don’t know if that was part of the problem.

  8. IV says:

    hey Konrad I figured out one of the reasons why the script was not working (which was i had downloaded the wrong archi-lab package) but i can figure out this next part. if you are not too busy today can you take a look and tell me why am i getting the warning “Warning: List.FilterByBoolMask operation failed.
    Specified cast is not valid” on the List.FinterByBoolMask node. I have attached a picture with the error.

    thank you in advance

    Attachment:  error1.png

  9. Sydney says:

    Hi Konrad,

    I was just wondering if there is a way to set the starting point for the door number – i.e: all the apartment entry doors will start at number 01 from the central lift core/lobby and then all internal doors will start clockwise from this entry door location.

    Thank you for your help

    • Sydney says:

      Update – I managed to figured out how to adjust the script to achieve what I wanted. – I posted the final solution here. My scripts is really messy but well it is working so yay~.

      And just want to thank you Konrad so such a good base script – it helped me to learn and understand a lot about Dynamo and Python.

    • Yes, I would sort the doors into groups that belong to each room and then sort them again in a clockwise order. I saw your later comment and it seems like you have it sorted out so I am happy for you. Great job!

  10. Karen says:

    Hello Konrad,

    Thank you for this definition and whole description. I’ve hit an impasse and hope you have time to help. I’ve got Dynamo 0.9.2 installed and have added the latest archi-lab package (2016.5.27) and Clockwork for Dynamo 0.7.x and 0.9.x. I’ve opened the definition and there are four nodes reported as not loaded;
    – Get Elements by Category/Level,
    – Phase Demolished,
    – Transform Origin and
    – Combine by Pattern
    Should I install a different version of Dynamo or the packages?

    Thank you, Karen.

  11. Tariq says:

    Hello guys , thank you so much for your big effort and amazing script and also for your time to help the beginner in dynamo like me
    can i ask question please ,!!!
    i tried to use this script in dynamo 1.1.02094 revit 2016 and i got this error as shown in the photo below can any one pleaaaaaaaaaaaaaaase help thanks alot

    Attachment:  Capture.jpg

  12. Sarah says:

    Hi there, I have downloaded all of the packages listed in this tutorial, but I cannot find the XYZ Components node as shown in the second to last screenshot. Can anyone help me to find it? I wonder if it’s changed names since this tutorial was created.


  13. Jeroen says:

    Hi Konrad, first of all thank you for sharing your work and the support you provide. I am trying to do something similar like you but get the following Python error:

    Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
    Traceback (most recent call last):
    File “”, line 65, in
    TypeError: expected Guid, got str

    Now I am not that familiar with coding. Could you help me what the problem here is? I get the same error in the dynamo sample you provided.

    Thanks in advance, Jeroen.

    Attachment:  Capture-1.jpg

    • Jeroen,

      On line 65. The Revit API changed recently in version 2016 i think, the get_Parameter call no longer accepts a name. You can either replace that with a call to to_Room.GetParameters(“Name”) or even better use the Built In parameter: to_room.get_Parameter(BuiltInParameter.ROOM_NAME).AsString(). Please look up the exact method online at as I can’t remember them exactly from top of my head. Cheers!

  14. Andres Montemayor says:

    This is great!

    I’ve started getting into Dynamo/Python myself and was wondering if there is a way to have it recognize if there is only one door to that room and have only the room number and if there is more than one, add the suffix.

    Anyway, thanks for this!

    • I am pretty sure that can be handled. I just never had a need for it so I don’t have an answer ready. Sorry.

      • Christopher Riddell says:

        This is great! Would adding a filter to look for if there are duplicate mark values in the script prior to adding the suffixes do this… some kind of if statement that says if there are more than 1 proceed with the script if not only use mark?

  15. Ricardo says:

    Hi Conrad thanks for this. I am running Revit 2018.2, Dynamo and Archilab 2018.0.8
    When I run the definition I don’t get any errors but I do get Empty lists past the List Map point. Truly lost as to what I am doing wrong.

    Any help would be awesome Thanks

    Attachment:  CaptureDoors2.png

  16. Dalton says:

    Hi Ricardo,
    Did you get it to work?

Leave a Comment