Automated Room Placement From Existing Drawings

Sometimes the only resource for existing conditions on a project are scans of original architectural drawings, often produced decades earlier. Scanning the drawings converts them into a digital form but these are flattened images from which no smart information can be extracted. Tracing walls, stair locations, and other building elements on top of a linked image underlay is relatively easy in Revit. Rooms however present a more difficult challenge because they are only represented by a text label and therefore many rooms may occupy the same open space. For example, a corridor may contain several appendages or alcoves that do not have physical elements separating them. This task becomes much more time consuming when placing a few hundred rooms across several levels of an existing building, which I was recently tasked with.

I began this investigation by converting the PDF scans into JPG files and opening them in Photoshop where I could quickly isolate the room names only. Once isolated, use a combination of the Gaussian blur tool, inverse select, and black color fill to convert the room name locations into a larger black blob then export each floor as a new JPG.

In Dynamo import the JPG containing the black blobs and scan the image for black pixels using the Image.Pixels and Color.Brightness nodes. You may have to try out several pixel values — using a large number in the xSamples input will generate too large of a pixel array and will take a long time to run, using too small a number may cause the node to miss some of the block blobs.

Rooms from Existing - Dynamo Definition (hi-res image available HERE)

Rooms from Existing - Dynamo Definition (hi-res image available HERE)

The Color.Brightness node returns a list of values between 0 and 1 that correspond to the brightness found in each pixel. Using some list management techniques, the list is inverted and then all white pixels (0s) are filtered out and only the darkest values (largest) are used to isolate the points where text values are located on the existing plan. Circles are created at all of the remaining points, with the radius defined by the corresponding darkness values. The entire list of circles should be matched against itself to group all intersecting circles because the Color.Brightness node may have read multiple block pixels in each text blob. Then extrude all the circles as solids, intersect any joining geometry, and use the Solid.Centroid node to determine the center point of each solid, which in theory should be the location point of each text label on the existing plans. A Count node can be used to evaluate the resulting number of text location points and determine if the total count of black blobs read in Dynamo closely matches the total number of room names labeled in the PDF scan.

If the counts are significantly different, adjust the pixel value sliders in the beginning of the definition to create a more or less dense field of points and re-trace the process up to this point. If the counts are close, the next step is to query the traced existing conditions walls from Revit model for the corresponding level. This can be done using combination of GetAllElementsOfCategory with the Category walls and then filtering only the elements on the same level.

Once the walls appear in Dynamo, you will most likely see that the resulting points from the existing plans will not be at the right scale, orientation, and location as the Revit walls. Placing a Geometry.Scale and Geometry.Node between the list of solids and the Solid.Centroid node will allow you to experiment with various scale and rotation values prior to the creation of final points. After some trial and error and visual approximation, you should be able to scale and orient the cluster of points to a configuration that matches the scale of the Revit model -- each point should look like it lands in the center point of each room.

Even after scaling and rotating the points, they may still be located off to the side of the Revit walls. To coordinate locations between Revit and Dynamo, begin by going to Manage > Setup > Line Style in Revit and create a new line called Dynamo. In the floor plan view of the level you are working on, pick a prominent element (such as a corner of the building) and draw a model line and change it to the newly created Dynamo line style. Back in Dynamo, use the Select Model Lines by Style node from the Archi-Lab package to locate the "Dynamo" line in Revit. Get the location at the start of that line using the Curve.Start node and also the location of origin in Dynamo with the Point.Origin node. A vector can now be established between these two points and used to translate all of the room locations scanned from the JPG to the same location as Revit. Note that moving from the Dynamo origin to the line drawn at the Level in plan should also move the room points to the correct elevation.

Once everything appears to line up correctly, the Tool.CreateRoomAtPointAndLevel node from the Steam Nodes package will place rooms at each point in the Revit model. For open areas such as corridors, multiple rooms will now be overlapping, potentially causing Warnings. The last step is to go through the model and draw room separation lines at logical points where divisions should occur between the room elements.

After every room has been separated in Revit, the process of populating Room Names, Numbers and other parameters is a manual one. However, if you are lucky enough to possess a CAD file for the existing conditions, Dynamo can also be used to populate the newly-created Room elements with text parameters. Begin by importing the CAD file into the Revit model and move it to the correct location. As a best practice, I tend to delete and purge all unnecessary layers in the CAD file prior to import -- in this case you may save a one-off of room text only and import that instead. In Revit if you explode an imported CAD drawing, the text will become actual Revit text objects (learn more HERE). With Dynamo, all text objects can be grouped into clusters based on shared location, matched up with the Room element center points, and then populate the associated elements with parameter information: Name, Number, Space Type, etc. Due to incongruent alignment or the use of leader lines, this workflow will most likely not work for every text item from the CAD plan but it may alleviate a large portion of the manual data entry required to populate the Revit room elements. More about this process in a future post...

Although a Dynamo-based approach requires some trial and error, it allows you to quickly place a large quantity of Revit Room elements in the exact same location as a scanned drawing. Knowing that the room locations are correct allows for quicker naming and parameter manipulation using Dynamo or other means and reduces a portion of monotonous work.