lisa-marie mueller

lisa-marie mueller

bullet pont

creating FilledRegions & Goal #2 Complete link

November 22, 2019

Laptop with code on screen, globe, game controller, green This week we continue on the path to automating interior elevations. As a reminder, I have been building a plug-in that automates various parts of creating interior elevations, and I will continue to develop it. Since this project will evolve as I continue, I have determined to set my primary goal for each stage. With this goal in mind, I will develop a functioning piece of software to meet the goal. Then I will discuss topics that cover key aspects for each step for building the plug-in. At the end of each stage, I will move the plug-in to a public repository on GitHub so you can use it too.

if you missed it:

Part 1: filtered element collector [c#]

Part 2: finding centroids and considering exceptions

Part 3: ViewFamilyTypeId

Part 4: ViewPlanId and Levels

Part 5: phases & goal #1 complete [includes GitHub link to the release]

Part 6: view tempaltes

Part 7: resizing CropBoxes

primary goal #2

Override the view’s parameters to set a view template, update the extents of the views, create a masking region, override the inside line weight of the masking region


Since we resized the CropBox, we now want to place our masking region. The reason a masking region can be helpful is that when you want to have the border of the interior elevation follow along door openings and changes in ceilings and soffits, it can be easier to do it with a masking region. It also makes it easier to adjust the line weight around the elevation rather than having to worry about overriding the display graphics of the interior elevation crop every time.

FilledRegion boundaries

Because we are using the filled regions to mask the parts around our view that are beyond the room, we need to create a donut-shaped filled region. Anything in the middle is visible and anything beyond that will be masked. For this, we need inside and outside boundaries.

We create a new public method that returns a list of CurveLoops which we will use to create our FilledRegion. We call it FilledRegionBoundary and it needs a ViewSection parameter which will be our interior elevation view. If you remember from Part 7, when we set the interior elevation view CropBox, we set it so that it was 1’-0” beyond the room in width and height. So when we get the bounds of the interior elevation CropBox, they will be 1’-0” beyond the room. This is why, for the inside boundary, we need to add 1 to the minimum value and subtract 1 from the maximum value. This will put the boundary back to the edge of the room. Also similar to Part 7, we have to perform some more transformations. I have to give a shoutout to my husband who helped me with the inverse matrices. If you remember, when you get the coordinates of the CropBox of the elevations view it uses the coordinate system of the view. However, to create our filled region, we need to work with the project coordinates. To to do this, we actually have to use an inverse matrix to reverse the translations and rotations back to the project coordinate system. I added these methods to a utility file for matrices. You can get access to it through my GitHub account. After we find the correct coordinates, we simply draw lines between them and add those lines to a list.

Since we want the outside curve to be set back from the CropBox a bit, we can take the CropBox coordinates and set them back 6”. Then we transform the coordinates with the inverse matrix as we did for the interior boundary. After we find the correct coordinates, we simply draw lines between them and add those lines to a list just like above.

Finally, we create a CurveLoop for both the inside and outside curves. We add both to a list of CurveLoops which we return to use to create our FilledRegion.

create FilledRegions

Now that we have the curves for the boundaries of our filled region, we just have to create the filled region. We create a new public method that does not return anything. It takes in our document, the interior elevation ViewSection, and the room’s BoundingBoxXYZ as parameters. The first thing we do is call our filledRegionBoundaries method to get our boundaries. Then we need to get the element Id of the type of filled region we want to create. Since we are using it to mask our view, we want the fill pattern to be white (RGB 255, 255, 255). For Revit 2019 and above, filled regions that are opaque have the IsMasking property set to true. You can also change the filters below or make them more specific if you need to. This code block then returns the TypeId of the filled region we need. We can then use this along with our interior elevation view’s Id and our boundaries to create our filled region. Finally, we override the line thickness to provide us with a thicker outline. For the code below, I just filtered for a line that contained “05” and “solid” in the name. It is more complex to filter for line style properties like the thickness and pattern. You may need to adjust the filter for the name based on how you name your lines.

add to Execute

Our final step is to add the methods we’ve created in Goal #2 to the Execute method. We circle through each elevation, overwrite the CropBox, create the filled regions, and adjust the line weight of the filled regions. This means that we have completed Goal #2. You can access the updated code on my GitHub account. There you can also download the DLL so you can use the updated plug-in too. Have fun!

Please note that since we have now added even more filters and hard-coded selections, there are a couple of things you need to use this plug-in as written. Your Revit file needs:

  • to have all the rooms placed for which you want to create the interior elevations
  • an elevation ViewFamily type with a name that contains “interior”
  • a ViewPlan with a name that contains “interior elevations”
  • a ViewTemplate with a name that contains “interior” and “elevation”
  • a FilledRegionType with the BackgroundPatternColor set to white (RGB 255, 255, 255)
  • a LineStyle with a name that contains “05” and “solid”

I’m taking a break next week because of the holidays, but check back December 6 for the next post in the series. That week, we set our 3rd and final goal so that everyone can enjoy automated interior elevations by the end of the year. Have a great turkey day!

code summary


If you want to learn to code and don’t know where to start check out my posts about Steps to Learn to Code [for architects and designers] Part 1 and Part 2.

Revit API Docs