FilledRegion Coordinates

Here is a

question

raised by Trang on how to access the coordinates of a filled region.

It demonstrates that you can make (completely unsupported and at your own risk) use of the sequential nature of the element id allocation to determine relationships between Revit database elements and their data that is not otherwise accessible through the Revit API.

Question: I try to get coordinates of corners of a FilledRegion but I couldn’t.
Could you show me how I can get the boundary of a FilledRegion?

Answer: The current Revit API does not provide any direct access to this data.

Meanwhile, however, just creating a filled region on the fly and using RevitLookup to analyse the results, I see that a FilledRegion element was created with the element id 161178.
Immediately before, a sketch with id 161176 was created. Its profile defines a curve array, and the lines are accessible.
Maybe this kind of approach can help you retrieve the data you are looking for?

Response: What I want is coordinates of a FilledRegion, so here is my code.


public List getBoundaryCorner(
  FilledRegion region,
  Document doc )
{
  List result = new List();
 
  ElementId id = new ElementId(
    region.Id.IntegerValue - 1 );
 
  Sketch boundary = doc.get_Element( id ) as Sketch;
 
  if( null != boundary )
  {
    CurveArray curBoundary
      = boundary.Profile.get_Item( 0 );
 
    if( null != curBoundary )
    {
      foreach( Curve cur in curBoundary )
      {
        XYZ corner = cur.get_EndPoint( 0 );
        result.Add( corner );
      }
    }
  }
  return result;
}

Answer: Congratulations on getting it working!

I created a new external command CmdFilledRegionCoords from your solution for The Building Coder samples.
For that, I updated your getBoundaryCorner implementation very slightly like this:


List<XYZ> GetBoundaryCorners( FilledRegion region )
{
  List<XYZ> result = new List<XYZ>();
 
  ElementId id = new ElementId(
    region.Id.IntegerValue - 1 );
 
  Sketch sketch = region.Document.get_Element(
    id ) as Sketch;
 
  if( null != sketch )
  {
    CurveArray curves = sketch.Profile.get_Item( 0 );
 
    if( null != curves )
    {
      foreach( Curve cur in curves )
      {
        XYZ corner = cur.get_EndPoint( 0 );
        result.Add( corner );
      }
    }
  }
  return result;
}

This helper method is driven by the following mainline in the Execute method implementation:


public Result Execute(
  ExternalCommandData commandData,
  ref string message,
  ElementSet elements )
{
  UIApplication uiapp = commandData.Application;
  UIDocument uidoc = uiapp.ActiveUIDocument;
  Application app = uiapp.Application;
  Document doc = uidoc.Document;
 
  List<Element> filledRegions
    = new List<Element>();
 
  if( Util.GetSelectedElementsOrAll(
    filledRegions, uidoc, typeof( FilledRegion ) ) )
  {
    int n = filledRegions.Count;
 
    string[] results = new string [n];
 
    int i = 0;
 
    foreach( FilledRegion region in
      filledRegions.Cast<FilledRegion>() )
    {
      string desc = Util.ElementDescription( region );
 
      List<XYZ> corners = GetBoundaryCorners(
        region );
 
      string result = ( null == corners ) ? "failed"
        : string.Join( ", ",
          corners.ConvertAll<string>(
            p => Util.PointString( p ) )
              .ToArray() );
 
      results[i++] = string.Format( "{0}: {1}",
        desc, result );
    }
    string s = string.Format(
      "Retrieving corners for {0} filled region{1}{2}",
      n, Util.PluralSuffix( n ), Util.DotOrColon( n ) );
 
    string t = string.Join( "rn", results );
 
    Util.InfoMsg( s, t );
  }
  return Result.Succeeded;
}

Here is a sample filled region to test this code on:

FilledRegion

Here are the resulting coordinates as displayed by the new overload of the InfoMsg method using a task dialogue:

FilledRegion coordinates

For completeness’ sake, here they are in text format as well:


Retrieving corners for 1 filled region:
Detail Items :
(-19.01,40.84,0),
(1.64,11.35,0),
(-35.7,17.93,0),
(-38.81,21.04,0)

Thanks to Trang for raising this topic and testing out the idea.

Here is
version 2012.0.92.0 of
The Building Coder samples including the new command CmdFilledRegionCoords.

Some additional notes: the element ids I originally saw in RevitLookup were not consecutive, but two apart.
Trang used consecutive ones, I am assuming after a more detailed analysis than my quick glance.

Obviously, the method described here is completely unsupported and will almost certainly fail in some future version.
You use it completely at your own risk.

Probably, at some point in the future, the Revit API will provide official access to the filled region coordinates, and this workaround will no longer be needed.

Still, it was pretty satisfying and good fun to make use of this undocumented feature, and also hear from Rudolf in his comment below that he is aware of it as well, for a similar use with revision clouds.


Comments

10 responses to “FilledRegion Coordinates”

  1. Rudolf Honke Avatar
    Rudolf Honke

    Hi Jeremy,
    I can confirm that this also does it with RevisionClouds.
    In that case, the sketch.Profile will contain straight lines instead of the arches we expect.
    The arches that we see in the RevisionCloud are the result of the fact that RevisionClouds use some kind of line-based 2D family. The resulting arches are self-similar, so we could get the arches by calculation.
    Cheers,
    Rudolf

  2. Dear Rudolf,
    Hey, great, thank you for the information!
    Cheers, Jeremy.

  3. Vitezslav Peka Avatar
    Vitezslav Peka

    Hi Jeremy,
    is there any way how to create filled region by using revit 2012 api
    thanks for reply
    Vita

  4. Dear Vitezslav,
    Nope, sorry. We have an open wish list item for it, though.
    Cheers, Jeremy.

  5. jude2012@126.com Avatar
    jude2012@126.com

    Hi Jeremy,is there a way to create a revision cloud by using revit api?

  6. Dear Jude,
    Nope, sorry, we have an open wish list item for that functionality.
    You may be able to make use of the known trick, described for instance by Rolando Hijar, who found a way to create railings using the Revit 2012 API before the introduction of the new railings and stairs in Revit 2013:
    “First I pick an existing railing and create a group of it. Then copy the group, ungroup and change the railing location line. I did this to place railings over the top of walls in a perimeter fence.”
    http://thebuildingcoder.typepad.com/blog/2009/02/list-railing-types.html?cid=6a00e553e16897883301676406fe61970b#comment-6a00e553e16897883301676406fe61970b
    Please let me know whether this can be used to create revision clouds. If so, I will promote it to a real main blog post of its own :-)
    Thank you!
    Cheers, Jeremy.

  7. Thanks Jeremy. Is there a way to actually draw filled regions by importing coordinates? A script which automatically creates filled regions from outside data?

  8. Dear Ek,
    Yes, you would use the static FilledRegion.Create method.
    Cheers, Jeremy.

  9. Michael Avatar
    Michael

    Jeremy,
    Any way to “tag” the area of a filled region? Maybe by using a piece of text or generic annotation that gets the area pushed into it?

  10. Dear Michael,
    You tell us exactly how to achieve it through the user interface, and we may be able to tell you how that can be automated.
    Cheers, Jeremy.

Leave a Reply to EKCancel reply

Discover more from Autodesk Developer Blog

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

Continue reading