I want to create a dimension for a legend by Revit 2018 API. When I run the Add-in, It Worked,but the dimension is invisible and the dimension value is a negative number. If i create a new detailline, and use the reference of the detailline, the dimension is correct. But i don't want to create detailline. what can i do?
this is my code:
Transaction trans = new Transaction(m_Doc);
trans.SetName("create dimension");
trans.Start();
Reference reference = uIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "pick a legend");
ReferenceArray references = new ReferenceArray();
Element element = m_Doc.GetElement(reference);
List<Edge> edges = GetEdges(element); //get two Parallel edges
references.Append(edges.ElementAt(0).Reference);
references.Append(edges.ElementAt(1).Reference);
Line left_edge = edges.ElementAt(0).AsCurve() as Line;
Line right_edge = edges.ElementAt(1).AsCurve() as Line;
Line line = Line.CreateBound(left_edge.GetEndPoint(0), right_edge.GetEndPoint(1));
Dimension dim = m_Doc.Create.NewDimension(view, line, references);
trans.Commit();
private List<Edge> GetEdges(Element element)
{
List<Edge> edges = new List<Edge>();
Options options = new Options
{
ComputeReferences = true,
IncludeNonVisibleObjects = false
};
var geoEle = element.get_Geometry(options);
foreach (var item in geoEle)
{
GeometryInstance geometryInstance = item as GeometryInstance;
if (geometryInstance != null)
{
GeometryElement geometryElement = geometryInstance.GetInstanceGeometry();
foreach (GeometryObject geoObject in geometryElement)
{
if (geoObject is Solid)
{
Solid solid = geoObject as Solid;
if (!solid.Faces.IsEmpty)
{
foreach(Face face in solid.Faces)
{
PlanarFace p_face = face as PlanarFace;
if (p_face.FaceNormal.IsAlmostEqualTo(XYZ.BasisZ))
{
EdgeArray edgeArray = p_face.EdgeLoops.get_Item(0);
foreach (Edge edge in edgeArray)
{
Line line = edge.AsCurve() as Line;
if (line.Direction.IsAlmostEqualTo(XYZ.BasisY) || line.Direction.IsAlmostEqualTo(XYZ.BasisY.Negate()))
{
edges.Add(edge);
}
}
}
}
}
}
if (edges.Count > 0)
{
break;
}
}
}
}
return edges;
}
Solved! Go to Solution.
Solved by FAIR59. Go to Solution.
If you want to dimension system families (walls, floors etc.), you are out of luck, it can't be done.
For user-families you have to use the symbol geometry
GeometryElement geometryElement = geometryInstance.GetSymbolGeometry();
Symbolgeometry is in local (family) coordinate space, so you have to transform it into model-space using the geometryInstance.Transform.
I found a way to create the dimension,but I don't know if it work correctly for all legend.
I create a dimension for a legend by UI, and use API to get the representation of the dimension's reference.
The string of representation is like this: element.UniqueId + ":0:INSTANCE:" + PlanarFace.Reference..ConvertToStableRepresentation(m_Doc).
So, in my add-in, when i get the planarfaces, I build the string, and use "Reference.ParseFromStableRepresentation()" to create reference. I create the dimension by the references. It work correctly.
When I create a dimension for a window in viewplan, I can get a center line of the window frame. But in a legend view, I can't get this line. If I want to dimension this. I must create a detailline ?