lisa-marie mueller

lisa-marie mueller

bullet pont

ViewPlanId and levels link

October 25, 2019

Laptop with code on screen, toy bird, toy rocket 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

primary goal #1

Create interior elevations for all placed rooms, place the tag at the center of the rooms, place the tag on the correct level when multiple levels exist, ensure the tag is visible on the interior elevation key plans (already in the project), and ensure the interior elevation tags have the proper phase settings


In order to place a ViewSection onto our ElevationMarker we need three parameters:

  • Document parameter - the document in which the ElevationMarker will be placed
  • ElementId parameter - ViewPlanId is the ViewPlan in which the ElevationMarker is visible, the ViewSection will inherit information from the ViewPlan
  • Integer parameter - to determine the index of the ElevationMarker at which the new view will be placed

Our document is just a variable that is passed through as an input. Our Integer parameter for the index will be a simple counter within a “for loop” so we don't need to use a method for its retrieval. This means we need to find the ViewPlanId. We start a new public method that returns a list of ViewPlans, and we call the list DocumentElevPlanViews. The only parameter it needs is the document input. This is where you need to evaluate how your project is set up. If you keep interior elevations visible in all plans, you can simplify the filtering of the FilteredElementCollector and just take the first plan it finds. However, some people have a plan just for interior elevation markers and keep them hidden in the rest of the plans. In this case, we filter down to plans that contain the name “interior elevations”. You need to make sure your plan names contain these words or adjust the string to accommodate your plan names.

So we have a new FilteredElementCollector and sort it down to the ViewPlans that contain the string “interior elevations”. Like always, if it returns null, we need to throw an exception.


One thing you may realize is that what we have done so far works great if we only have a one story building, but if we have more than one story, our DocumentElevPlanViews list will contain multiple plans and the CreateElevation method requires just one ViewPlan. For multiple levels, we need to check which ViewPlan the Room is visible on. We create a new public method that returns a ViewPlan and call it GetViewPlanOfRooms. Since we are looping through rooms to place our elevations, we will do the same here. We will loop through each room and check that room against all the ViewPlan elements in our list. Once we find the ViewPlan that it is in, we will return that ViewPlan. If you have hundreds of levels with hundreds of plans in your model, this will take a while and you may want to consider optimizing this method, but for most buildings it will run fast enough.

Now we can add to the PlaceElevations method we started in Part3 and place the elevations. We have a simple “for loop” to start at index 0 and then increase to the remaining indices until we get to the MaximumViewCount for the ElevationMarker.

We almost have a functioning plug-in. Next week, we complete the final task of ensuring the interior elevation tags have the proper phase settings. Then we can write the method that will execute our program and we are finished with Goal #1.

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