Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to get the total width and length of the design using Revit API C# ?

3 REPLIES 3
Reply
Message 1 of 4
Anonymous
2103 Views, 3 Replies

How to get the total width and length of the design using Revit API C# ?

Hi,

 

I am using Revit API 2015 and Visual Studio 2013.

 

 

I want to get the total width (along x-axis) and the total depth/length (along y-axis) of the given design. Does anyone know what would be the best way to achieve it using Revit API.

 

Any suggestions will be much appreciated.

 

Many Thanks and Kind Regards

Bilal

3 REPLIES 3
Message 2 of 4
jeremytammik
in reply to: Anonymous

Dear Bilal,

 

The number of possible approaches is infinite.

 

I would probably start off by computing the convex hull of the entire design, and then determine the width and length of that:

 

http://thebuildingcoder.typepad.com/blog/2009/06/convex-hull-and-volume-computation.html

 

Another approach, which may or may not be faster, depending on many factors:

 

Skip the convex hull part and just iterate over all building elements, enlarging a bounding box containing all their vertices as you go along:

 

  bounding box B = (+infinity, -infinity)

  for all elements
    for all element geometry vertices P
      if P < B.min: B.min = P
      if P > B.max: B.max = P

Another approach, definitely faster than the last:

 

Use the element bounding box vertices instead of all the element geometry vertices.

 

All of these approaches would make very nice little samples.

 

There are certainly more ways to approach this task. 

 

I have a strong personal tendency towards the pure geometric.

 

Implement them and provide the code and a couple of examples designs to test them on, including extreme cases, and I'll clean it up and publish it for you on The Building Coder.

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 4
jeremytammik
in reply to: Anonymous

Funnily enough, a very similar question was raised shortly after by another developer:

 

Question: Is there a built-in method to get a bounding box of the entire model, similar to the method Element.get_BoundingBox?

 

The only way I see right now is to use IExportContext, go through all the visible elements and get the minimum and maximum coordinates among the all points. But on the large models this method may take a while.

 

Is there some faster method?

 

Answer: Yes, maybe.

 

As I already suggested above, there are a number of possibilities:

 

  • Compute the convex hull of the entire design, and then determine the width and length of that:

 

http://thebuildingcoder.typepad.com/blog/2009/06/convex-hull-and-volume-computation.html

 

  • Skip the convex hull part and just iterate over all building elements, enlarging a bounding box containing all their vertices as you go along:

  

  bounding box B = (+infinity, -infinity)
 
  for all elements
    for all element geometry vertices P
      if P < B.min: B.min = P
      if P > B.max: B.max = P

 

  • A faster approach: use the element bounding box vertices instead of all the element geometry vertices.

 

One aspect that I did not mention that makes a huge difference for large models:

 

The bounding box of all elements is immediately available from the element header information, and thus corresponds to a quick filtering method, whereas all the approaches that require the full geometry correspond to a slow filter.

 

Using a custom exporter, like you suggest, is also a good idea, and corresponds to a slow filter.

 

If you are interested in good performance in large models, I would aim for a quick filter method, e.g., like this:

 

  public static class JtBoundingBoxXyzExtensionMethods
  {
    /// <summary>
    /// Expand the given bounding box to include
    /// and contain the given point.
    /// </summary>
    public static void ExpandToContain(
      this BoundingBoxXYZ bb,
      XYZ p )
    {
      bb.Min = new XYZ( Math.Min( bb.Min.X, p.X ),
        Math.Min( bb.Min.Y, p.Y ),
        Math.Min( bb.Min.Z, p.Z ) );
 
      bb.Max = new XYZ( Math.Max( bb.Max.X, p.X ),
        Math.Max( bb.Max.Y, p.Y ),
        Math.Max( bb.Max.Z, p.Z ) );
    }
 
    /// <summary>
    /// Expand the given bounding box to include
    /// and contain the given other one.
    /// </summary>
    public static void ExpandToContain(
      this BoundingBoxXYZ bb,
      BoundingBoxXYZ other )
    {
      bb.ExpandToContain( other.Min );
      bb.ExpandToContain( other.Max );
    }
  }
 
  #region Get Model Extents
  /// <summary>
  /// Return a bounding box enclosing all model
  /// elements using only quick filters.
  /// </summary>
  BoundingBoxXYZ GetModelExtents( Document doc )
  {
    FilteredElementCollector quick_model_elements
      = new FilteredElementCollector( doc )
        .WhereElementIsNotElementType()
        .WhereElementIsViewIndependent();
 
    IEnumerable<BoundingBoxXYZ> bbs = quick_model_elements
      .Where<Element>( e => null != e.Category )
      .Select<Element,BoundingBoxXYZ>( e
        => e.get_BoundingBox( null ) );
 
    return bbs.Aggregate<BoundingBoxXYZ>( ( a, b )
      => { a.ExpandToContain( b ); return a; } );
  }
  #endregion // Get Model Extents

 

I implemented that for you and included it in The Building Coder samples release 2017.0.127.6:

 

https://github.com/jeremytammik/the_building_coder_samples/releases/tag/2017.0.127.6

 

Response: So, in fact I was right and the only method is to get this information from the geometry.

 

I’ll benchmark with CustomExport (as I suggested) and FilteredElementCollector (as you did) with large models and let you know.

 

I think your way should be faster, but not correct in some cases:

 

Case 1) Linked models. It doesn’t consider linked models if they are.

 

Case 2) Even if we extend this method and get the elements geometry from the linked models, we need to transform the coordinates from linked model to the hosted model, as BoundingBox returns the coordinates in a source model.

 

Case 3) Your method returns all the elements. In my case I need only the view specific Model BoundingBox. Yes, we can use FilteredElementCollector with ActiveView, but it can be a section view or 3d view bounded by section box.

 

Therefore, FilteredElementCollector should be faster, but needs to consider all the cases (maybe there are more than I mentioned). As CustomExporter iterate only the visible geometry, exactly like it presented on the view, this way is more reliable.

 

Anyway, the benchmark will show the results ☺

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 4 of 4
jeremytammik
in reply to: Anonymous

Dear Bilal,

 

Thank you for your query.

 

I summarised, cleaned up and published our conversation on The Building Coder:

 

http://thebuildingcoder.typepad.com/blog/2016/08/vacation-end-forge-news-and-bounding-boxes.html#8

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Rail Community