Several cases recently came up asking how to obtain references to programmatically create dimensioning elements.
These hints expand on the recently discussed topic of creating dimensioning between family instance insertion points.
They were raised by the following queries on how to retrieve suitable references for dimensioning:
Before getting to that, I'll just add that I returned safe and sound from the Dubai hackathon that I mentioned last Friday.
I reported on the event during the weekend, discussing hackathon preparation in general, the View and Data API workshop and the hackathon projects presented.
Back to the Revit API and the topic at hand:
Question: I want to get the reference planes in a family instance for dimension creation with the API.
For example, use the API to create a dimension between the centre references of two windows.
The following test code, for example, does not find the reference planes I need:
public void ListFamilyGeometry( UIDocument uidoc ) { Document doc = uidoc.Document; Reference r; try { r = uidoc.Selection.PickObject( ObjectType.Element ); } catch( Autodesk.Revit.Exceptions .OperationCanceledException ) { return; } FamilyInstance fi = doc.GetElement( r ) as FamilyInstance; if( fi == null ) { return; } Transform transform = fi.GetTransform(); string data = string.Empty; Options options = new Options(); options.IncludeNonVisibleObjects = true; foreach( GeometryObject go in fi.get_Geometry( options ) ) { data += go.GetType().ToString() + Environment.NewLine; if( go is GeometryInstance ) { GeometryInstance gi = go as GeometryInstance; foreach( GeometryObject goSymbol in gi.GetSymbolGeometry() ) { data += " - " + goSymbol.GetType().ToString() + Environment.NewLine; if( goSymbol is Line ) { Line line = goSymbol as Line; makeLine( doc, transform.OfPoint( line.GetEndPoint( 0 ) ), transform.OfPoint( line.GetEndPoint( 1 ) ) ); } } } } TaskDialog.Show( "data", data ); }
Answer: I assume you have read about dimensioning between family instance origins.
If your window symbols have their insertion points at the same location as the centre reference, you could use that approach.
To address your real requirement, though, you need to retrieve the centre references directly.
Here are some important aspects that you need to keep in mind to retrieve the references to create dimensioning between the centre references of two family instances, e.g. windows:
These aspects have been mentioned in the past; still, I hope it helps to spell them out explicitly again here and now.
The following query was raised by Samer Habib in a comment on What's New in the Revit 2016 API:
Question: I am trying to create a new dimension between a grid and an edge of a face.
I get the reference of grid by grid.Curve.reference and I get the reference of the face edge.
However, in the NewDimension method the references argument requires an array of geometric references to which the dimension is to be bound.
The grid does not seem to have any such geometric reference.
Therefore, when I call the NewDimension method, it throws an 'Invalid number of references' error.
How can I solve this, please?
Answer: The answer is exactly the same as above:
Please note the description of dimensioning between instance insertion points, plus these additional important aspects:
Response: Yes!
I now set the options like this:
Options goption = new Options(); goption.ComputeReferences = true; goption.IncludeNonVisibleObjects = true; goption.View = doc.ActiveView;
That returns the grid geometry and the problem is solved.
Here is another query on dimensioning to a specific location that does not directly provide any built-in references of its own:
Question: Can the API be used to create a dimension to the wrapping location of an insert in a wall?
Here is an example of the desired dimension:
If it is not possible to get a reference to this location, can the location be found so a detail line can be created which could be used for the dimension?
Answer: Yes, this location can be found as described in the discussion on retrieving detailed wall layer geometry.