We want to create dimensions between grids.
In version 2015 and before, we can get grid reference from Grid.Curve.Reference and it's OK to create dimensions.
In version 2016, previous reference doesn't work, in this forum, we get the idea that use following code to get the grid reference:
Options opt = new Options();
opt.ComputeReferences = true;
opt.IncludeNonVisibleObjects = true;
opt.View = doc.ActiveView;
foreach (GeometryObject obj in grid.get_Geometry(opt))
{
if (obj is Line)
{
Line line = obj as Line;
if (line.Reference != null)
{
return line;
}
}
}
In version 2017, both methods are failed. Any help is highly appreciated.
BTW, looks like the Revit API is highly UNSTABLE !!!
I didn't try the code, but maybe this works:
Grid g = Grid.Create(doc, Line.CreateBound(new XYZ(0.0, 0.0, 0.0), new XYZ(10.0, 0.0, 0.0))); Reference r1 = g.Curve.GetEndPointReference(0); Reference r2 = g.Curve.GetEndPointReference(1);
Let me know.
regards
Christian
No. This only works in 2015 or ealier version. Fail in 2016 and 2017
Just tried this in 2017, no lucky. Both DatumExtentType (Model and ViewSpecific) are fail to get curve reference
Hi
Try this Code I have tested on 2016 and 2017
if and only if the Grid lines are parallel the Code will work. so as an improvement, you need to double check the vector direction of each line is exactly the same.
<code>
Snippet
using Autodesk.Revit.UI; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.Attributes; namespace trace_documentchanges { [Transaction(TransactionMode.Manual)] class Class1 : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { Document m_doc = commandData.Application.ActiveUIDocument.Document; var uidoc = commandData.Application.ActiveUIDocument; using (Transaction t = new Transaction(m_doc, "Create Grid Dim")) { t.Start(); dim_Grid(m_doc); t.Commit(); } return Result.Succeeded; } public static void dim_Grid(Document m_doc) { var filcol = new FilteredElementCollector(m_doc, m_doc.ActiveView.Id).OfClass(typeof(Grid)); ///get a grid reference line ReferenceArray gridRefs = new ReferenceArray(); List<XYZ> Dimlocpoint = new List<XYZ>(); foreach (Grid grid in filcol) { Options opt = new Options(); opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = true; opt.View = m_doc.ActiveView; foreach (GeometryObject obj in grid.get_Geometry(opt)) { if (obj is Line) { Line line = obj as Line; gridRefs.Append(line.Reference); if (Dimlocpoint.Count < 2) { if (Dimlocpoint.Count == 0) { Dimlocpoint.Add(line.GetEndPoint(0)); } else { line.MakeUnbound(); Dimlocpoint.Add(line.Project(Dimlocpoint[0]).XYZPoint); } } } } } create_Dimensions(m_doc, Dimlocpoint[0], Dimlocpoint[1], gridRefs); } static Dimension create_Dimensions(Document m_doc, XYZ p1, XYZ p2, ReferenceArray Refsar) { return m_doc.Create.NewDimension(m_doc.ActiveView, Line.CreateBound(p1, p2), Refsar); } } }
</code>
Hi, I know this may be late now, and properly the asker has found a resolution. but I discovered something and I forgot to mention it here. if the Grid Center segment properties is set to "Custom" or "NONE" the reference is always null, but if set to "Continuous" it works fine. hope this answers your question.
The problem is not that you can't find the reference, the problem is that the newDimension method rejects the reference.
I manually made a dimension between 2 grids. The reference for the grid from the dimension was the same as the reference you get from grid.Curve.Reference. (checked by comparing the reference.ConvertToStableRepresentation() value strings.
So I presume there is a bug in the newDimension method. To test I wrote a macro to recreate a manually made dimension. You would think that the references (dimension.References) from a existing dimension are valid for the creation of a new dimension.
For lines (detail and model) the macro works. However for grids ( and reference planes) the macro fails !!!
@jeremytammik : could you check the attached document with macro, and see if you also think it's a bug?? (revit version 2018)
Not sure if this is a bug or by design in terms of not recognising references of type REFERENCE_TYPE_SURFACE.
When dimension is attached to lines these are REFERENCE_TYPE_LINEAR which it recognises. When you recreate the reference from a refereceplane or grid element these are REFERENCE_TYPE_NONE which it also recognises. However when you directly use the references in the reference array of the original dimension these are REFERENCE_TYPE_SURFACE which it doesn't like.
The below works:
Public Function Execute_DimRefPlane(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData, _ ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) _ As Autodesk.Revit.UI.Result Dim UIDoc As Autodesk.Revit.UI.UIDocument = commandData.Application.ActiveUIDocument If UIDoc Is Nothing Then Return Result.Cancelled Else IntDoc = UIDoc.Document Dim R As Reference = Nothing Try R = UIDoc.Selection.PickObject(Selection.ObjectType.Element) Catch ex As Exception End Try If R Is Nothing Then Return Result.Succeeded Else Dim D As Dimension = TryCast(IntDoc.GetElement(R), Dimension) If D Is Nothing Then Return Result.Cancelled Else Dim Arr As New ReferenceArray For Each item As Reference In D.References Dim El As Element = IntDoc.GetElement(item) Arr.Append(New Reference(El)) Next Dim RefTypes As New List(Of ReferenceType) For Each Rx As Reference In Arr RefTypes.Add(Rx.ElementReferenceType) Next Dim DirLN As Line = TryCast(D.Curve, Line) Dim Dir As XYZ = DirLN.Direction Dim Origin As XYZ = D.Origin.Add(New XYZ(3, 0, 0)) Using Tx As New Transaction(IntDoc, "Dim") If Tx.Start = TransactionStatus.Started Then 'Taking directly from reference array of dimension not working 'Does it ignore surface references, error says wrong number of refs but count is 2? Try IntDoc.Create.NewDimension(IntDoc.ActiveView, Line.CreateBound(Origin, Origin.Add(Dir) * 2), D.References, D.DimensionType) Catch ex As Exception End Try 'Duplicating the reference array IntDoc.Create.NewDimension(IntDoc.ActiveView, Line.CreateBound(Origin, Origin.Add(Dir)), Arr, D.DimensionType) Tx.Commit() End If End Using Return Result.Succeeded End Function
@RPTHOMAS108 Your statement that the NewDimension method does't like references of type SURFACE is too strong. References to faces of walls, Generic Model families etc. will be accepted.
That is true yes.
It seems to expect references for ref planes and grids in particular to be REFERENCE_TYPE_NONE, not sure why.
I think I found the post that mostly solves this issue, at least is shed some important light.
I also incorporated that information and the items here and provided a more complete example in Python.
Located at the link below.
Dear @FAIR59 Frank,
Thank you for your request for me to report this issue to the development team and reproducible case.
To submit it, I need to summarise the issue and provide a succingt description of the exact issue and steps to reproduce:
http://thebuildingcoder.typepad.com/blog/about-the-author.html#1b
The development team requires the following information:
They are probably unwilling and possibly even unable to wade through this entire thread and extract the information from that.
Could you please provide that?
Thank you!
Best regards,
Jeremy
Hi, guys
I've faced with the same problem yesterday and today I saw this theme. I've take a shallow look at this and linked discussions, may be I repeat somebody's answer. But I've solved this problem in that way: instead of getting references from grid curve I got reference to entire grid element:
var gridRef = Reference.ParseFromStableRepresentation(doc, grid.UniqueId);
May be there are some cases it won't work, I don't know at this moment
Hi
I've been struggling with this a bit as many of you. Unfortunately no previous solution worked in my case.
But I've found out that we can do some tricks.
I changed the type of reference tweaking the string reference.
Note that I also eliminated the last :0 part. I reviewed the references in a dimension using Jeremy's Revit Lookup tool and strangely they have surface references.
Anyway, I tried this and works:
foreach (Grid g in item.Value)
{
string sampleStableRef = g.Curve.Reference
.ConvertToStableRepresentation(vs.Document);
string Refer = sampleStableRef.Replace("0:SURFACE", "LINEAR");
var gridRef =
Reference.ParseFromStableRepresentation(vs.Document, Refer);
if (gridRef.ElementId != null)
{
refArray.Append(gridRef);
}
}
if (refArray.Size > 1)
{
Dimension ds = vs.Document.Create.NewDimension(
vs, lineref, refArray, tipoDim);
}
Is not a BUG, grids are just a different type of element. The dimension reference can't be created by constructing a stablereference.
This has been asked and answered many times on the forum.
https://forums.autodesk.com/t5/revit-api-forum/invalid-number-of-references/m-p/9503522
use, never had a problem with it.
// GridElementid = the id of the grid instance.
Grid grid1 = (grid)doc.GetElement(GridElementid);
ReferenceArray DimRefs = new ReferenceArray;
DimRefs.Append(new Reference(grid1));
- Michel
Thx~, I will give it a try. 😁
I solved the problem by constructing it straight from UniqueId, like @aignatovich suggested. Works fine, thx! 😁
I worked with linked elements mostly (including linked Grid), assembling a stable representation from pieces of string is my go-to option for quite a long time, ReferenceArray never rejected. It happened yesterday when I tried to add dimension to a local Grid.
I think constructing stable reference for linked Grid still works. So the only odd ball I encountered so far is local Grid. @TripleM-Dev.net Is there any other "a different type of element" I should worry about?
I mostly dimension walls and User families and only then dimension actual geometry (solids), so I haven't come across any other elements with different behaviour.
Would think levels behave similar to grids..both derived from DatumPlane types
Maybe directshape objects.
- Michel