How Dynamo Can Help Limit the Usage of Revit Model-In-Place Families

How Dynamo Can Help Limit the Usage of Revit Model-In-Place Families

In the previous post, where I shared my opinion on why it does not matter if you use Revit the right way, I had a paragraph on Model-In-Place families in Revit. I do not know about others, but I personally never liked seeing them in BIM models and try not to use them anymore. Though, I did use my fair share of them, enough to realize how many issues it can lead to later. From quantity issues, to accidentally modified geometry of these components and worse of all, how these accidental modifications can seriously break large parts of the model once you have many elements that are hosted on that element or related to it in some other way, through dimensions or whatnot. It can be frustrating fixing all these families or getting them to conform to your established Revit workflow.

Other aspects that annoy me is the lack of reusability. You cannot save them and load them into other projects. Sure, there are workarounds by saving as a group, but I stopped using that glitch after I once corrupted a Revit model to which I have loaded this “extracted” model-in-place family. The reusability aspects also apply within the same project as well. If you copy the model in place family, it will create a new one. Leading to a growing Revit file size, slightly degrading the performance of the model and a few extra headaches.

Why do people use Model-In-Place feature?

So, with all the potential issues and shortcomings of the Model in Place components, why do people still use them so frequently? Well, the most common answer I have received regularly from asking this question, is – “Oh, I can then see the model in the background and it is easier and more convenient to model the geometry that way”. As much as I would like to argue with that, I just end up like in the following meme…

That argument is a pretty solid one from a user’s perspective. It is convenient to model that way when you can see the entirety of the model in the background for reference. Particularly this is useful for those one-off cases or when you model some hosted components that are of slightly irregular or more complex shape. For those of us that have worked with Revit long enough or consider ourselves as power users, the standard family editor of a typical loadable family does not cause any discomfort. But there are plenty of users that do not focus on the Revit or BIM aspects but more on the architecture or engineering aspect of the design process. They just need to get the project done; hence they use whatever is easier and quickest for them. It is somewhat strange that Autodesk has not tried to find a suitable solution for this in some way.

The Dynamo solution

One solution I see is to allow the model to be visible inside the loadable family editor or at least have an extracted view of a certain part of the model. Thought I would give this a shot with Dynamo, to see what can be done. The result I came up with is surprisingly a simple 2-part Dynamo script. It is all thanks to the two geometry nodes: Geometry.ToSolidDef and Geometry.FromSolidDef. The core concept is to extract the necessary amount of geometry from the Revit model, the project around a point of interest, in this case, a surface/face. Load that geometry back into a family editor of a proper loadable family in such a way that this imported geometry is transformed to align with the reference plane of the family editor.

I will show both scripts and then briefly explain the what and the why of each part. One aspect to keep in mind is that I based the script around the fact that a user will likely have a certain surface in mind as the reference plane from which the geometry will be modelled. There are several ways to go about the script, so the solution presented below might not necessarily be best for your case. Either way, feel free to modify it as necessary for your own needs.

Part 1 – Getting the geometry

The first part of the script revolves around retrieving the surface as the planned reference plane and the surrounding geometry.

Dynamo script 1 - Get Reference Geometry From Project

Click on the image above to enlarge it, should scale up to full resolution for those that want it. Nonetheless, I will be going over each group of nodes below.


1 – The inputs I decided to use include a location to the file that the geometry will be temporarily saved to. I could have used the file path node but decided to just use the string node. The main reason is that I can just type in the file name and extension of the yet non-existent file as I want and it will later create a file with that name and write the contents to it. In essence, it does not matter if you use the string approach or the file path node approach. The remaining inputs are what matter most in this script. The user must select a face of an object within the Revit project which will determine the reference plane that the user intends to work on once the geometry is imported into a family editor environment. The offset around the surface is a number node where the user enters the value that will be used to extend a cutting cube around the edges of the selected face. If the value is equal to 0, then the dimensions of the cutting cube will be determined by the extends of the selected face. I will explain the cutting cube thingy a bit further. Note: If you want to run this script through Dynamo Player do not forget to right-click on these nodes and check Is Input.

Dynamo script_1_parts_2_3_4

2 – This part retrieves the coordinate system located at the midpoint of the selected face and the point at that same location. The point is needed to mark the centre of the cutting cube. The coordinate system is later used to transform the extracted geometry from the project to properly face the reference plane within the family editor.

3 – To limit how much geometry is transferred into the family editor, the script creates a cube around the midpoint of the selected face with dimensions equal to the extents of the surface + the user-specified offset. Usually, you would only need a bit of geometry for reference, not the entire project. Even if the user wanted the entire project, a very large offset can be given at it would work fine.

4 – This part is meant to retrieve all the elements present in the active view, filter out those that contain solid geometry. Depending on how heavy your model is, this part will take the longest part of the script to run. Generally, it is quite fast even with larger projects. The user has the option to just use a filtered Revit view that only shows what is needed. There are other ways to get this done in terms of filtering and elements so feel free to experiment.

Dynamo script_1_part_5

5 – This node group takes the previously defined cube and checks which of the elements coming in from group 4 are intersected by this cube. For simplicity and cleanliness, I attempt solid.ByUnion on the filtered element geometry. It might not always work due to numerous reasons. Therefore, there is also an IF statement that passes through the joined geometry or all the individual element geometries separately if they cannot be joined. Lastly, the geometry gets cut and the list is flattened. An alternative way could be to go for the Geometry.Intersect from the start. Again, feel free to add your personal touch to the scripts.

The Python Node within the group is a simple IF code. There are multiple ways to make one, but the rule of thumb so far is to avoid the included one in Dynamo. It is prone to behaving weirdly, resulting in unexpected outcomes. The code:

if IN[0] is None:
    OUT = IN[1]
    OUT = IN[0]
Dynamo script_1_parts_6_7

6 – This code group takes the geometry from 5 and the coordinate system from 2 to transform the geometry to align with the origin of the Revit model. This is mostly to ensure that the geometry is at the origin before being imported into a family editor environment. Afterwards, the magic component of this script, the Geometry.ToSolidDef node. It takes the geometry and stringifies it. Therefore, it can be written to a simple text file and read back later when needed. The string.join node is there to ensure that when solid.ByUnion node failed and multiple geometries were output, they could all be written to a single string.

7 – This node just writes the string into the specified file to be retrieved with part 2 of this Dynamo script.

Part 2 – Loading the geometry into a family editor

Now that the user has collected and saved the geometry of interest from the project, we need to import it back into the family of interest. A user would start the creation of the family from the desired family template and then run the second part or should I say the second Dynamo script.

Dynamo script 2 - Load Reference Geometry Into Family Editor

1 – Select the file to which the geometry was saved. Do not forget to set this node as Is Input if you intend to run in through the Dynamo Player.

2 – The strings from the file are then read and split by the previously specified separator. The geometry is then recreated with the Geometry.FromSolidDef node.

3 – To bring the geometry into the family editor environment, I used the Form.ByGeometry node from the awesome springs nodes package. It can be replaced but it works well in this scenario.

A quick demo of the scripts in action

Note: in certain scenarios, the geometry might end up facing the wrong way in the family editor, flipped about the selected surface. Just easily mirroring it around the reference plane will set it right again. Once the geometry is inside the family editor, it can be transformed as needed.

Dynamo script download links

For the sake of learning, you could recreate the script with your own twist, or just download the finished script from the link below.


It can be quite annoying having to deal with too many Model-In-Place families in a Revit project. Unless there is a better proposition for an average Revit user, these families will not be going anywhere anytime soon. I am hoping that Autodesk will come up with some sort of solution or some improvements. Until that happens, the Dynamo workaround I have shown in this post could serve as a temporary solution. There are certainly other ways to go about this as the current approach is tailored around a few constraints. Namely, requiring the selection of the surface as a base reference plane and temporarily storing the geometry data inside a separate file.

If you are wondering if Dynamo could be used to solve some other particular problem you and your company is facing, do not hesitate to drop us a quick inquiry, we might be able to help!