Sphere Creation for AVF and Filtering

I created my first sphere in the Revit API :-)

I was slightly surprised that it was harder than expected.
The Revit 2012 API introduced the GeometryCreationUtilities class for creating solids.
It provides no simple sphere primitive, however.
It does provide the following five methods, as described in the What’s New listing for the Revit 2012 API:

GeometryCreationUtilities

The new utility class GeometryCreationUtilities offers the ability to create solid geometry from input curves:

  • CreateBlendGeometry
  • CreateExtrusionGeometry
  • CreateRevolvedGeometry
  • CreateSweptGeometry
  • CreateSweptBlendGeometry

The resulting geometry is not added to the document as a part of any element.
However, you may use the created solid, and its constituent faces and edges, in several ways:

  • As the input face(s) to the methods in the Analysis Visualization Framework AVF, e.g. SpatialFieldManager.AddSpatialFieldPrimitive.
  • As the input solid to finding 3D elements by intersection.
  • As one or more of the inputs to a Boolean operation.
  • As a part of a geometric calculation using, for example, Face.Project, Face.Intersect, or other Face, Solid, and Edge geometry methods.

The resulting solids created thus reside only in memory, cannot be added to the Revit database and not saved.
So what good are they?

As said, you can use them for display purposes via the Analysis Visualization Framework

AVF
,
or to limit filtered element collection to a localised space, as input to an ElementIntersectsSolidFilter filter.
I haven’t presented any samples using this filter so far, and I promise to do so soon in a follow-up post.

Scott Conover showed some interesting uses in his AU and DevDays presentations on the

Revit 2012 geometry API enhancements
,
and I picked that up to show how to use AVF to

display room volumes
.

Before getting to that, though, let’s just create a spherical solid in the first place.

Creating a Sphere

One way to create a spherical solid using the GeometryCreationUtilities methods listed above is by using the CreateRevolvedGeometry method.
I can create a face loop representing a half circle, e.g. a 180 degree arc with a line between its endpoints, and then rotate that 360 degrees around the line, which also defines the axis of revolution.

A so-called frame needs to be specified for the solid creation.
To enable creation of a sphere in any location, I wish to pass in the sphere centre point and radius as arguments.
I can use the centre point to define the frame location.
I initially thought that the face loop is defined at the global origin, and the frame automatically translates it into place, but that led to the following exception being thrown, saying that the “loops must lie on the right side of the Z axis (where X >= 0)”:

Sphere creation exception

I fixed that by translating my loop definition to the same centre point as the frame, and end up with the following implementation:


  /// <summary>
  /// Create and return a solid sphere with
  /// a given radius and centre point.
  /// </summary>
  static public Solid CreateSphereAt(
    CreationApp creapp,
    XYZ centre,
    double radius )
  {
    // Use the standard global coordinate system 
    // as a frame, translated to the sphere centre.
 
    Frame frame = new Frame( centre,
      XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ );
 
    // Create a vertical half-circle loop;
    // this must be in the frame location.
 
    Arc arc = creapp.NewArc(
      centre - radius * XYZ.BasisZ,
      centre + radius * XYZ.BasisZ,
      centre + radius * XYZ.BasisX );
 
    Line line = creapp.NewLineBound(
      arc.get_EndPoint( 1 ),
      arc.get_EndPoint( 0 ) );
 
    CurveLoop halfCircle = new CurveLoop();
    halfCircle.Append( arc );
    halfCircle.Append( line );
 
    List<CurveLoop> loops = new List<CurveLoop>( 1 );
    loops.Add( halfCircle );
 
    return GeometryCreationUtilities
      .CreateRevolvedGeometry(
        frame, loops, 0, 2 * Math.PI );
  }

Displaying a Solid Using AVF

One of the uses of the transient solids created by the geometry creation utility class is for geometrical filtered element collection.
Before we get to that, however, lets simply display a couple of spheres using the analysis visualisation framework AVF.

I copied and posted code from the samples mentioned above to create an AVF display style, get or create a SpatialFieldManager, and set up an analysis result schema.
All this functionality is finally accessed by a simple call to the PaintSolid method.

Here is my external command Execute mainline implementation putting it all together:


  public Result Execute(
    ExternalCommandData commandData,
    ref string message,
    ElementSet elements )
  {
    UIApplication uiapp = commandData.Application;
    UIDocument uidoc = uiapp.ActiveUIDocument;
    Application app = uiapp.Application;
    CreationApp creapp = app.Create;
    Document doc = uidoc.Document;
 
    Solid s1 = Command.CreateSphereAt(
      creapp, XYZ.Zero, 1.0 );
 
    Solid s2 = Command.CreateSphereAt(
      creapp, new XYZ( 44.051020645,
        80.747278319, 9.842519685 ), 1.0 );
 
    Solid s3 = Command.CreateSphereAt(
      creapp, 5 * XYZ.BasisX, 3.0 );
 
    Solid s4 = Command.CreateSphereAt(
      creapp, 10 * XYZ.BasisY, 5.0 );
 
    PaintSolid( doc, s1, 1.0 );
    PaintSolid( doc, s2, 2.0 );
    PaintSolid( doc, s3, 3.0 );
    PaintSolid( doc, s4, 4.0 );
 
    return Result.Succeeded;
  }

Some of the resulting spheres look like this in Revit:

Spheres displayed using AVF

Next things I am thinking of doing are using a sphere to define a localised geometrical filtered element collector, and also making use of Kean’s

Apollonian gasket
and

sphere packing


web service
to
fill a sphere with solid spheres
(project overview).
The latter may not be all that useful in the BIM domain, but fun.


Comments

14 responses to “Sphere Creation for AVF and Filtering”

  1. Hi Jeremy,
    nice to see that you are planning to use Kean’s web service.
    One thought:
    In contrary to AutoCAD, there are length limitations that one must have in mind when creating geometrical objects.
    So it may be that you cannot create too tiny spheres; also, it may happen that you cannot create the lines and arcs which you need for the rotation operation.
    And so on…
    Cheers,
    Rudolf

  2. Dear Rudolf,
    Thank you for the hint. Yes, I thought of that already. I’ll just have to make them really big, then.
    Cheers, Jeremy.

  3. Hi Jeremy,
    as far as I know, there is also an upper size limitation in Revit files.
    So please avoid to generate objects of planetary scale…
    ;-)
    Cheers,
    Rudi

  4. Jeremy,
    What lovely looking balls you have there!
    Is it possible to scale a ball ‘up’ (eg make your balls even bigger) – maybe scale it up a ‘percentage’ …
    Ive been looking at the post from March 17, 2009 ‘Transform’ http://thebuildingcoder.typepad.com/blog/2009/03/transform.html
    Im trying to figure out how to use ‘ScaleBasis’
    Could you demonstrate how to enlarge your balls using this method?
    Many Thanks!
    Kon.

  5. Dear Kon,
    :-)
    I am tempted to treat you comment as a joke.
    Seriously speaking, just change the radius.
    Cheers, Jeremy.

  6. Jeremy,
    Glad I could put a smile on your face… but if an object has been made, how can I use ScaleBasis to enlarge something?
    Regards,
    Kon.

  7. Dear Kon,
    Please remember that Revit is not AutoCAD:
    http://thebuildingcoder.typepad.com/blog/2012/02/bim-versus-free-geometry-and-product-training.html
    Forget TransformBy.
    Imagine scaling a wall by a factor of two. What happens? Its width doubles. What does that mean? It is no longer the same wall type. The neww required wall type does not even exist. Basically, forget scaling in Revit. You change the type, or you change the parameters. You do not scale.
    Of course, if you are working with pure geometrical objects, then you might be able to scale something. That is then purely abstract and has nothing to do with BIM elements or the real world.
    Best regards from AU in Las Vegas!
    Cheers, Jeremy.

  8. Jeremy,
    Its been a while, but I need to re-visit your balls!
    I take your point about AutoCAD and indeed I would not want to scale a family or other object.
    I need to scale a ‘solid’/’GeometryElement’ for a bit of ‘rough What-If’ visual analysis…
    Sometimes its a complex shape, so I cant re-create the element (easily)
    Is there a way to scale up a soild from its ‘center point’ or centroid?
    Ive been playing around with ScaleBasis and every time I apply it, the object moves as well!
    Cheers,
    Kon

  9. Dear Kondaments,
    Nope, sorry.
    I searched very hard for something similar:
    “It would be great if there was a possibility to grow the solid just slightly, e.g. offset all its faces outwards by an inch or two or define a tolerance before executing the intersection check, like for the bounding box. Unfortunately, growing or shrinking an arbitrary solid is much harder than a bounding box and therefore not implemented.”
    Here are some of the alternatives that I explored:
    http://thebuildingcoder.typepad.com/blog/2013/03/supporting-columns.html
    Cheers, Jeremy.

  10. Hi Jeremy,
    I must have missed that post … ooops.. I usually read all of them very closely.
    Just a quick one then, in the above linked post you mentioned that you nudged the solid down a little .. how did you do it? That may in fact be all that I need.
    eg. make a 2 copies of the Origional solid
    So OrigionalSolid, copyA, copyB
    nudge copyB down a bit
    union copyA and copyB both together, that makes a new (larger) solid (solidC).
    This time, create only one copy, dudge it in another direction then join that to SolidC …..
    repeat as necessary…
    Cheers,
    Kon.

  11. Dear Kon,
    Please download the source code from that post and look:
    http://thebuildingcoder.typepad.com/blog/2013/03/supporting-columns.html
    http://thebuildingcoder.typepad.com/files/getbeamcolumns06.zip
    I normally never delete anything, just comment out the parts that I end up not using, so it should still be in there somewhere.
    Cheers, Jeremy.

  12. Thanks!
    I will let you know how I go!
    Cheers,
    Kon.

  13. Hi Jeremy
    What happen if the solid is being created without applying the AVF? Is the solid still states in the Revit model and making the Revit file bigger?
    Thanks

  14. Dear Sarkate,
    No, the solid is in-memory only. It is not a Revit database element.
    Cheers, Jeremy.

Leave a Reply

Discover more from Autodesk Developer Blog

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

Continue reading