Thursday, 5 February 2009

Calculating building height - again

My last post was an attempt to calculate building height, but I quickly realised after posting (and luckily before being rumbled by some smart alec) that what I was doing was calculating the height at which the uppermost level was placed. Any thing on the uppermost level was being ignored.

So, here's another idea, and it assumes that your building has a roof at the top, which I'm sure in most cases is a fair assumption(?). It uses a category filter to look for roofs and then it queries the Max Z value of the BoundingBox of the roof:

Dim element As Autodesk.Revit.Element
Dim zValue As String

'active view used later for boundingbox
Dim activeView = revitApp.ActiveDocument.ActiveView

'get all elements in the Roof category
Dim CatFilter As Autodesk.Revit.Filter
CatFilter = revitApp.Create.Filter.NewCategoryFilter(Autodesk.Revit.BuiltInCategory.OST_Roofs)


Dim result As New List(Of Autodesk.Revit.Element)
Dim NumLevels As String = revitApp.ActiveDocument.Elements(CatFilter, result)

       
For Each element In result

'change this to footprintRoof etc if you wish            
If TypeOf element Is Elements.ExtrusionRoof Then


If element.BoundingBox(activeView).Max.Z > zValue Then
    zValue = element.BoundingBox(activeView).Max.Z
End If
   
WriteOutput(element.BoundingBox(activeView).Max.Z)

End If

Next

You could of course remove the 'If TypeOf' conditional and replace it with a try catch which would be a cheeky way of looking for the Max.Z in every element that the roof category filter returns, catching those that don't support it, and returning values for those that do. This would then return the Max Z value for all types of roof in your model.

In fact that's given me an idea. How about this, this will scan through every element in your model and return the largest Z value it can find. Is this the height of your building? :

Dim elementIterator As Autodesk.Revit.ElementIterator
elementIterator = revitApp.ActiveDocument.Elements

Dim topElement As Autodesk.Revit.Element
Dim element As Autodesk.Revit.Element
      
Dim zValue As Double
zValue = 0
Dim activeView = revitApp.ActiveDocument.ActiveView

While (elementIterator.MoveNext())

 element = elementIterator.Current

 Try
  If element.BoundingBox(activeView).Max.Z > zValue Then
   zValue = element.BoundingBox(activeView).Max.Z
   topElement = element
  End If
 Catch ex As Exception
  Debug.Print(Err.Description)
 End Try

End While

WriteOutput("The highest Z value is: " & zValue)
WriteOutput("The element is: " & topElement.Name)
WriteOutput("The element ID is: " & topElement.Id.Value)

The answer is no, I just tried this last idea on the Revit training sample c_Condo_Complex.rvt and of course it takes a long time to run, but it gave me the value for the 3D view. If you look for all elements, they won't all be part of your building!

So stick with the first idea above. I bet there'll be a comment in soon telling me there's a really easy way to do this, like building.height :)

No comments:

Post a Comment

Comments are moderated, so you'll have to wait a little bit before they appear!