Retrieving Column and Stair Geometry

We have had several questions related to the retrieval of the geometry of stair elements in the past.
<!– e.g. from
Zorcad,
Ritish
[2],
Arjun,
and
Shifali
[2,
3].
–>
We already explored the geometry of various other elements, e.g.
slab boundary,
slab side faces,
wall elevation profile,
2D polygon areas and outer loop,
3D polygon areas,
cylindrical columns, and
MEP ducts.

Here is now a solution by Joe Ye which may shed some new light on this issue.
The main point is that all elements which are represented by instances of a symbol may either have their own local geometry assigned to them, if it is unique in some way, or they may be reusing the standard geometry defined for the family type, transformed to their local insertion point, if it can be reused unmodified and thus shared with all other instances.

Question: I am trying to access the geometry data of different building elements in order to rebuilt them from their meshes and convert them to another format.
I had no problems converting walls, but some other objects don’t provide access to their geometry data in the same way.

Problem #1: Columns.
I am filtering out all columns as FamilyInstances.
When I use the sample Revit ‘Urban House’ model, I can access their geometry, get the related solid and access the mesh from its faces.

On the other hand, when I apply the same approach to another model of my own, this is not possible.
In this model, the attempt to cast the GeometryObjects to solids returns null.
Is there maybe something wrong with this model or the families used in it?

Another Problem here is filtering for columns which are not of the structural type StructuralType.Column.
I am doing this by accessing the Family.Instance.Category.Name which is not very elegant.

Problem #2: Stairs.
The problem I have with stairs is that I can cast the GeometryObjects to solids, but they do not contain any faces.
Is there maybe a different way to access the geometry of stairs, so that I can create a mesh from it?

Answer: The issue with the columns is that the ones used in your own sample model file are standalone columns which do not join or intersect with any other elements.
If a column or some other FamilyInstance element is joined to another element, its geometry might be changed by this operation.
Therefore, each instance needs to maintain its own specific copy of the geometry.

On the other hand, a standalone column or FamilyInstance object that does not cut any other element can reuse the unmodified geometry defined by its family symbol.
This helps reduce file size, since it avoids creating and maintaining multiple copies of the same geometry.

We therefore need to check whether the family instance geometry contains any solid of its own.
If not, then it may be a standalone element, and we need to look at the symbol’s geometry instead.
The standalone element type geometry is accessible through Geometry > Instance > SymbolGeometry.
The geometry retrieved then needs to be transformed from the symbol definition coordinate system to the instance coordinate system by applying the transform retrieved from Geometry > Instance > Transform.

Here is a pseudo code example demonstrating this:


void generateSingleElement( RvtElement e )
{
  GeoElement geo = e.get_Geometry( geomOption );
 
  if( geo != null )
  {
    GeometryObjectArray arr = geo.Objects;
 
    foreach( GeometryObject obj in arr )
    {
      Solid geomSolid = obj as Solid;
 
      if( null != geomSolid ) //+
      {
        // get geometry from this solid
        // ...
      }
      else if( obj is GeoInstance )
      {
        GeoInstance geoInst = obj as GeoInstance;
 
        GeoElement geoElem = geoInst.SymbolGeometry;
 
        Transform transform = geoInst.Transform;
 
        GeometryObjectArray arr2 = geoElem.Objects;
 
        // use the same method as above to obtain 
        // the nested geometry. please don't 
        // forget to convert with the transform.
        // ...
      }
    }
  }
}

The other problem you mention is filtering the columns which do not have the structural type StructuralType.Column.
You need to be aware of the fact that a StructuralType is only applicable to structural elements, for example structural columns and structural beams.
Normal architectural column instances will not have a structural type assigned to them, so you cannot use this method to filter for them.
In that case, you should use the more general approach of filtering for the desired combination of FamilyInstance type and column category.

Regarding your issue with stairs, the solution is the same as for the columns.

Many thanks to Joe for handling this solution!


Comments

13 responses to “Retrieving Column and Stair Geometry”

  1. Christian Schwöbel Avatar
    Christian Schwöbel

    Hi Jeremy,
    thank you for posting this solution!
    I tried another approach, which also seems to work. I accessed the Instance Geometry of the Geometry Element. Is there any difference between Symbol Geometry + Transform and Instance Geometry?
    Autodesk.Revit.Geometry.Element geoElement = geoInst.GetInstanceGeometry();
    GeometryObjectArray geoInstObjectArray = geoElement.Objects;
    Cheers, Christian

  2. Dear Christian,
    Thank you for your appreciation and sorry for the belated answer, I just returned from a vacation.
    Yes, there may be a difference between the two, cf.
    http://thebuildingcoder.typepad.com/blog/2010/02/unmodified-element-geometry.html
    I hope that helps explain.
    Cheers, Jeremy.

  3. Hi Jeremy,
    Is it possible to get the actual storage size of any Revit element as it is sized in its Revit file?

  4. Dear Jeff,
    I am not aware of any such possibility. I would also assume that the storage size depends on a huge number of factors. If there is some specific element that you are interested in, I would try the following:
    1. Create an empty project and save it in a file A.
    2. Create a certain number N elements of the type you are interested in, preferrably at least a couple of thousand, and save that in a file B.
    3. Calculate the file size used per element as (size B – size A) / N.
    Cheers, Jeremy.

  5. Jeremy,
    I appreciate the help and suggestion. I am actually interested in all elements in a Revit file, determining size relationships. An elements should be sized relational to its properties and type, but it would help to have a function that when loading a project one could optionally parse each element size when it is not yet in its runtime loaded state.
    Jeff

  6. Dear Jeff,
    What an unusual request. What do you need this for, please?
    Cheers, Jeremy.

  7. Jeremy,
    This was a request that was given to me. I would imagine from a top down perspective if one knew potential bottlenecks in a project in terms of element category sizes etc, one could better approach layouts and planning of a Revit project, especially in a group or team setting.
    Jeff

  8. Dear Jeff,
    Seems like a very strange thought to me. Sorry, I cannot suggest anything beyond what I said above.
    Cheers, Jeremy.

  9. Dear Jeremy Tammik
    is that possible to get stair vertics to make reinforcement plugin for it ?

  10. Dear Basel,
    You can easily find out for yourself. Simply select a stair object and use RevitLookup to snoop the current selection. If you can read the stair geometry and access its solid, you can get the vertices from there.
    Cheers, Jeremy.

  11. Jeremy,
    I followed the above code and was able to retrieve the nested geometry solid. Any chance you could post a few pointers how you’d go about transforming the solid to the instance coordinate system?

  12. sorted…
    I used the getTransform method
    :)
    answer was staring me right in the face the whole time!

  13. Dear Brett,
    Cool, congratulations.
    Cheers, Jeremy.

Leave a Reply to bbCancel reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading