Creating a Dimension Label

In a comment on the discussion of the

family API
,
Nadim asked how to create a label in a family document, and Harry Mattison of Autodesk very friendlily provided some sample source code to generate a new dimension label.
I hope this is what you were looking for.

Question: I am trying to use the FamilyItemFactory to create a label inside the family document.
I can see all kinds of creation functions like NewDimension, NewSweep, NewTextNote, but I can’t find any function to do NewLabel.
You can do that in the family editor user interface, so it should be possible through the API as well, shouldn’t it?
The label might be the most common element used in Annotation Families.

Answer: As said, Harry provided a code snippet to create a dimension label in a family document, which I used to implement a new Building Coder sample command CmdNewDimensionLabel.

It creates two model lines which provide the references required to define a dimension and sets up the appropriate reference array.
The reference array is used when calling NewLinearDimension to create a new dimension entity between the two lines.
Finally, a new family parameter named “length” is created and associated with the dimension label.

When I first tried to run this in a new family document based on the annotation family, I was told by Revit that the creation of a new sketch plane is not allowed in that context, so I added a helper method findSketchPlane which returns a sketch plane from the given document with the specified normal vector, if one exists, or else null:


static SketchPlane findSketchPlane(
  Document doc,
  XYZ normal )
{
  SketchPlane result = null;
 
  List<Element> a = new List<Element>();
 
  int n = doc.get_Elements(
    typeof( SketchPlane ), a );
 
  foreach( SketchPlane e in a )
  {
    if( e.Plane.Normal.AlmostEqual( normal ) )
    {
      result = e;
      break;
    }
  }
  return result;
}

Unfortunately, in the next step, I noticed that the model lines used in this sample are not allowed in an annotation family either, so I just ran the command in a column family document instead.

Here is the mainline of the CmdNewDimensionLabel external command Execute method which performs the following steps:

  • Find or create an appropriate sketch plane to work on, with a normal vector of (0,0,1).
  • Create two vertical geometry lines.
  • Create two vertical model curves from the lines.
  • Collect the two references to the model lines in a reference array.
  • Create a dimension entity between the two lines.
  • Create a family parameter named “length” for the dimension label.
  • Associate the dimension label with the “length” parameter.

Application app = commandData.Application;
Document doc = app.ActiveDocument;
 
SketchPlane skplane = findSketchPlane( doc, XYZ.BasisZ );
 
if( null == skplane )
{
  Plane geometryPlane = app.Create.NewPlane(
    XYZ.BasisZ, XYZ.Zero );
 
  skplane = doc.FamilyCreate.NewSketchPlane(
    geometryPlane );
}
 
double length = 1.23;
 
XYZ start = XYZ.Zero;
XYZ end = app.Create.NewXYZ( 0, length, 0 );
 
Line line = app.Create.NewLine(
  start, end, true );
 
ModelCurve modelCurve
  = doc.FamilyCreate.NewModelCurve(
    line, skplane );
 
ReferenceArray ra = new ReferenceArray();
 
ra.Append( modelCurve.GeometryCurve.Reference );
 
start = app.Create.NewXYZ( length, 0, 0 );
end = app.Create.NewXYZ( length, length, 0 );
 
line = app.Create.NewLine( start, end, true );
 
modelCurve = doc.FamilyCreate.NewModelCurve(
  line, skplane );
 
ra.Append( modelCurve.GeometryCurve.Reference );
 
start = app.Create.NewXYZ( 0, 0.2 * length, 0 );
end = app.Create.NewXYZ( length, 0.2 * length, 0 );
 
line = app.Create.NewLine( start, end, true );
 
Dimension dim
  = doc.FamilyCreate.NewLinearDimension(
    doc.ActiveView, line, ra );
 
FamilyParameter familyParam
  = doc.FamilyManager.AddParameter(
    "length",
    BuiltInParameterGroup.PG_IDENTITY_DATA,
    ParameterType.Length, false );
 
dim.Label = familyParam;
 
return CmdResult.Succeeded;

Here is the dimension and the associated dimension label created in a new family document based on the metric column template:

Dimension with dimension label

The length displayed in millimetres, and corresponds to the 1.23 feet specified by the variable ‘length’, since 1.23 * 12 * 25.4 = 374.904.

As noted above, this code will not work unchanged in an annotation family, because you are prohibited from creating model curves there.
To run it in an annotation family, you will have to convert the code to work with

detail curves

instead.
You also cannot create a new sketch plane in an annotation family document, which was what prompted me to implement the findSketchPlane helper method.

Here is
version 1.1.0.61
of the complete Building Coder source code and Visual Studio solution including the new command.

Many thanks to Harry for this solution!


Comments

14 responses to “Creating a Dimension Label”

  1. Hi there Jeremy,
    for the passed few months i have been reading your blogs once in a while, pure out of curiousity. i have been working with Revit some time now, i a really want to dive more into the coding part of it.
    now i saw that you have put the source for download, but when trying to juist build it, and add it to the revit menu i get this error:
    “Revit cannot run the External Command “buildingcoder”. Contact the provider of this external tool with the information below:
    system.typeloadexeption while creating instance of ‘buidlingcoder’in “C:.….\buildingcoder.dll
    could not load type ‘buildingcoder’ from assambly ‘buildingcoder, version=2.0.0.0, Culture=neutral, Publickeytoken=null”
    now, i dont have much experience with coding and building dll files, so i might be making some really stupid mistakes.
    Cheers
    Dante

  2. Dear Dante,
    There is lots of material answering your question in the Getting Started category of this blog. I suggest you look there. Before you try to install the Building Coder samples, it will help to implement and install your own minimal plug-in. The best way to learn to do that is probably to watch and work through the DevTV presentation:
    http://thebuildingcoder.typepad.com/blog/2009/12/updated-devtv-introduction-to-revit-programming.html
    Cheers, Jeremy.

  3. Hi Jeremy,
    is there a way to position or move the label of a Dimension?
    We got that possibility in the interface: we select the Dimension and we can drag the label around.
    I’ve looked at the Dimension properties and functions and could not find anything about the positioning of the text.
    Thanks for your insight !
    Ben

  4. Dear Ben,
    Sorry, I cannot find any access to this information either. I also just discovered that RevitLookup fails for me when I try to snoop the dimension element.
    If you find a solution for this, please let us know. Thank you!
    Cheers, Jeremy.

  5. Jeremy,
    I implemented the code you have above (with modifications for detail lines) and was able to get it to work inside of the family editor.
    I wanted to see if I could do something similar with with text note, but haven’t had any luck.
    I am able to create a text note(via vb.net), but I can’t assign a label to it.
    It looks like labels are a different type anyway.
    snooping:
    a label –> TextElement
    a textnote –> TextNote
    Dim myTextElement As TextElement
    app.Create.NewTextNoteCreationData <– ??? not sure if that’s the direction i should head in…and if so how to do it.
    Is it possible to create a text label?
    …gregory

  6. Dear Gregory,
    Congratulations on getting it to works with detail lines.
    NewTextNoteCreationData is nothing more than a driver for creating large numbers of text notes, so it adds no functionality that is not available through the NewTextNote method.
    I don’t know about the text label creation. At least I cannot find any open wish list items for it, so I would assume you can create them.
    Cheers, Jeremy.

  7. Hi Jeremy Tammik,
    I have a one doubt, it is possible to create the Dimension label on elevation view. E.g., I have create the two family instance(structural column or beam) in 3D view, select the two instance and run the command, its create the Dimension label on between the distance. pls give some idea.
    Right now i want to create the Automatic Dimension. I can create the Elevation (like ColumnandBracess to create the elevation) that time i want to create Dimension also. so pls guide me
    Best & Regards,
    Dharnaidharan R

  8. Dear Dharnaidharan,
    That sounds feasible to me. Short of going ahead and doing it, however, I have no additional guidance to provide on this, and I don’t have time to try implementing it right now.
    Good luck and best regards, Jeremy.

  9. Hi Jeremy Tammik,
    I need u r help very urgent. I had create the linear dimension for all structural beam by using Geometry object -> line -> and get the (start and end)line arrayreference to assign and create the Dimension.
    Now, my problem is im not able to get geometry object (start and end point) for Structural column. so my quary
    1. How to get Structural Column Referencearray (then only im assign the Dimension)
    2. Its return only Location Point, then how to identify the structural column height.
    Thanks in advance
    Dharanidharan R

  10. Dear Dharanidharan,
    If you really need serious help urgently, I suggest you contact a professional consultant.
    I am only doing this for fun, you know.
    If the column is vertical, it would normally go from one level to another, wouldn’t it? So you can obtain its height from the level Elevation property.
    One way to get references is to shoot a ray along the column axis and retrieve the top and bottom faces using FindReferencesByDirection:
    http://thebuildingcoder.typepad.com/blog/2010/01/findreferencesbydirection.html
    Cheers, Jeremy.

  11. Hi Jeremy,
    Hope you are doing good.
    I am working with macros for Revit. Above code did not work for macro. Please suggest code to label dimension for macro.
    Thanks in advance.
    Neelima

  12. Dear Jeremy,
    How can I create dimension lable for pipe for its length in project document in Revit 2014 Api.

  13. Dear James,
    You can dimension a pipe length just like any other Revit element.
    For your convenience, I put together a new topic list on creating dimensioning:
    http://thebuildingcoder.typepad.com/blog/about-the-author.html#5.45
    I hope this helps.
    Cheers, Jeremy.

  14. Dear Neelima,
    Thank you, I hope you are too.
    Sorry, I am not aware of any significant differences between executing this as a stand-alone add-in or a macro.
    Cheers, Jeremy.

Leave a Reply to BenCancel reply

Discover more from Autodesk Developer Blog

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

Continue reading