is not always the correct approach.
It’s been too long since my last post. My blogging time has been occupied by more personal projects, some of which I’ll post about soon (famous last words ;-) ).
I’m always keen to hear from people pushing Revit. In this case the person has immense knowledge of the Revit family editor and some knowledge but no real experience of the API. As required in their jurisdiction, when scheduling windows and doors they have to schedule areas of natural light. These exclude frames and mullions and have to be a percentage of the room area. In other words the visible glazing area per room. Here is the schedule in the test project. Glazing area is just the windows width*height. Natural light area is the glass area and Percent Natural light is (Natural light area/ room area)%.
The first issue they faced is you can’t schedule room area in door and window schedules. Strange, because you can schedule volume but using this and relying on unbounded height to get the area is not a reliable solution. So this is having to be manually entered. AAGH!!!!
The second issue and really the basis for this post is that of calculating the area of natural light. Their solution was to add reference planes and width/height parameters to the window family to define each extrusion representing the areas of glass. And then use these values from the width/height parameters to sum the areas of glazing. Straightforward, except when the window in question looks like this:
This resulted in 25 parameters and an ungodly array of formulae. I totally understand why they have taken this approach. For many the API is like a foreign language and so they have to push the family editor to achieve the desired result. They’ve used best practice techniques for building families and on the face of it , it all looks good. However, this is so not the path BIM and Revit should be taking you down.
Oh dear…
From a Revit development perspective it shows how much there is left to do with the family approach to component creation and management. From an API perspective it shows how inaccessible it is for most, particularly when it is a much better tool for the job as in this situation. Developing and testing this family has been a lot of work, and that’s just the one family. For every different style of window they’re going to have to repeat the process.
Here are the main issues as I see it are:
1.. 25 parameters in one family is a serious documentation and maintenance issue in one family. In a whole series of window families it’s a potential nightmare as you are repeating the formulae in every different family. It also has the potential to be a performance hit in a project of any size.
2.. Yes you could use nesting, but it doesn’t really help much. You still need to aggregate the areas, and you still have the maintenance issues.
3.. Every window series that is different requires a new array of formulae. There is a high risk of someone changing a formula in one family and not updating all associated families. What if you want to use the window in a different jurisdiction and a possibly different approach to calculating the area of natural light? Localisation becomes a problem.
4.. Code compliance analysis has no place in Revit families. Natural light calculations are not specific to the design of the window but rather a generic rule applied to all windows in a project. In software programming this is referred to as separation of concerns. Applying/adding or modification of compliance rules should not require touching the Revit family at all in an ideal world.
The API approach
So how can the API help?
The first thing to do is automate the room area updates. Next is to remove the requirement for customising window families to calculate glazing areas. We can use the API to automatically calculate the natural light areas (glass) from the family geometry. This obviously changes with family type so we need to account for this.
Find attached a 2010 Revit project with a VSTA document macro embedded which does all this. In a production situation I’d use a standard API command, but for this prototype a VSTA macro is adequate.
The approach I’ve taken is to extract the area of glass from the extrusion for the types used in the project. To do this we need to know which geometry is glazing. We could have used the material but they tend to vary within projects and families can have multiple glass materials in one family. Instead the macro looks for extrusions with a glass subcategory.
To get at this subcategory requires editing the family as category isn’t exposed by getting the windows instance geometry in the project.So this is a 2010 project or above. Not the fastest approach but adequate as the parameters vary by window type only. You’d only need to run the macro whenever :
1.. A new window type is used in a project.
2.. The width/height of the window type change.
3.. The room area changes. (This update could be a separate command)
To get the actual glazed area in a family type we check for extrusions which have a subcategory equal to ‘glass’
if (e.Category.Name == "Glass")
{
var GeomM = e.get_Geometry(_geomOption);
foreach (var img in GeomM.Objects)
{
var ss = img as Solid;
var fc = ss.Faces[0];
nlArea += fc.Area;
}
}
Not a very robust solution for production but good enough to show the point. The beauty of this approach is it works for round or unusual shaped windows without any complexity being added to the family to calculate the area. The issues as prototyped include:
1.. Faces[0] assumes the extrusion has been built in elevation.
2.. the modelled boundaries of the glazing can’t extend into the window frame or mullions. Or the areas will be wrong.
3.. It assumes only one glazing subcategory. Probably ok in most situations.
I’ve documented the code but if there are any questions please add a comment.