Add dimension to all edges in selected face - magic error...

Add dimension to all edges in selected face - magic error...

BBKENGJS
Contributor Contributor
738 Views
7 Replies
Message 1 of 8

Add dimension to all edges in selected face - magic error...

BBKENGJS
Contributor
Contributor

I'm getting a "magic" Error in Revit2023 :"The dimension type is a non-linear dimension type" using the attached code. The dimension type is linear, the number of references is equal 2 ... Any suggestions ? 

 

Public Sub AddDim()

Dim r As Reference = _uiDoc.Selection.PickObject(ObjectType.Face, "Select a face")
Dim e As Element = _uiDoc.Document.GetElement(r)
Dim view As View = _uiDoc.ActiveView
Dim oFace As Face = e.GetGeometryObjectFromReference(r)
Dim edges As EdgeArray = oFace.EdgeLoops(0)
Dim dimensionStyle As DimensionType = New FilteredElementCollector(view.Document).OfClass(GetType(DimensionType)).Cast(Of DimensionType)().FirstOrDefault

'Dim offset As Double = 0
MessageBox.Show(view.Name.ToString) 'CHECK
Using trans As New Transaction(_doc, "Add Wall Dimensions")
trans.Start()
If dimensionStyle Is Nothing Then
Throw New Exception("No dimension style found in document")
End If
MessageBox.Show(dimensionStyle.Name.ToString)
For Each edge As Edge In edges
MessageBox.Show(edge.ApproximateLength.ToString) 'ONLY INFO
Dim eline As Curve = CType(edge.AsCurve(), Curve)
Dim pts As XYZ
Dim pte As XYZ
pts = eline.GetEndPoint(0)
pte = eline.GetEndPoint(1)
MessageBox.Show(pts.ToString & pte.ToString) 'ONLY INFO
Dim refArray As ReferenceArray = New ReferenceArray()

' Check whether eline is a line and add the endpoints to the reference array
If TypeOf eline Is Line Then
Dim line As Line = CType(eline, Line)
refArray.Append(line.GetEndPointReference(0))
refArray.Append(line.GetEndPointReference(1))
Else
refArray.Append(eline.GetEndPointReference(0))
refArray.Append(eline.GetEndPointReference(1))
End If

MessageBox.Show(refArray.Size.ToString) 'ONLY INFO


If refArray.Size = 2 Then
Dim dimRef As Dimension = _doc.Create.NewDimension(view, eline, refArray, dimensionStyle) 'Error in Revit2023 :"The dimension type is a non-linear dimension type"
End If
Next
trans.Commit()
End Using
End Sub

0 Likes
Accepted solutions (1)
739 Views
7 Replies
Replies (7)
Message 2 of 8

caroline.gitonga
Autodesk
Autodesk

Hi @BBKENGJS,

There are 3 kinds of dimensional types: Angular, Linear and Radial.

This error is most probably that you are assigning wrong type of dimension style while creating the dimension.

First step, would be to lookup the properties of the dimension style elements you wish to apply on your dimension and see if its the type you want.

For ref, kindly go through this resource and you may find more relevant information to help solve this:
Carol Gitonga, Developer Advocacy and Support, ADN Open
0 Likes
Message 3 of 8

BBKENGJS
Contributor
Contributor

Thank You for the explanation. I slightly modified the code to be sure  that the  dimension type is Linear

but now I'm getting in Revit 2023 ERROR: "Invalid number of references".

But the number of References is 2. Can You please help me solve the problem?

 

Public Sub AddDim()

Dim r As Reference = _uiDoc.Selection.PickObject(ObjectType.Face, "Select a face")
Dim e As Element = _uiDoc.Document.GetElement(r)
Dim view As View = _uiDoc.ActiveView
Dim oFace As Face = e.GetGeometryObjectFromReference(r)
Dim edges As EdgeArray = oFace.EdgeLoops(0)
Dim dimensionStyle As DimensionType = New FilteredElementCollector(view.Document).OfClass(GetType(DimensionType)).Cast(Of DimensionType)().LastOrDefault

'Dim offset As Double = 0
MessageBox.Show(view.Name.ToString) 'CHECK
Using trans As New Transaction(_doc, "Add Wall Dimensions")
trans.Start()
If dimensionStyle Is Nothing Then
Throw New Exception("No dimension style found in document")
End If
MessageBox.Show(dimensionStyle.Name.ToString)
For Each edge As Edge In edges
MessageBox.Show(edge.ApproximateLength.ToString) 'ONLY INFO
Dim eline As Curve = CType(edge.AsCurve(), Curve)
Dim pts As XYZ
Dim pte As XYZ
pts = eline.GetEndPoint(0)
pte = eline.GetEndPoint(1)
MessageBox.Show(pts.ToString & pte.ToString) 'ONLY INFO
Dim refArray As ReferenceArray = New ReferenceArray()

' Check whether eline is a line and add the endpoints to the reference array
If TypeOf eline Is Line Then
Dim line As Line = CType(eline, Line)
refArray.Append(line.GetEndPointReference(0))
refArray.Append(line.GetEndPointReference(1))
Else
refArray.Append(eline.GetEndPointReference(0))
refArray.Append(eline.GetEndPointReference(1))
End If

MessageBox.Show(refArray.Size.ToString) 'ONLY INFO


If refArray.Size = 2 Then
Dim dimRef As Dimension = _doc.Create.NewDimension(view, eline, refArray, dimensionStyle) 'Error in Revit2023 :"Invalid number of references"
End If
Next
trans.Commit()
End Using
End Sub

 

0 Likes
Message 4 of 8

caroline.gitonga
Autodesk
Autodesk

Hi @BBKENGJS,

Kindly, follow through this forum thread regarding 'Invalid Number of references' when creating Dimension.

https://forums.autodesk.com/t5/revit-api-forum/newdimension-between-grids-invalid-number-of-referenc...

 

https://forums.autodesk.com/t5/revit-api-forum/invalid-number-of-references-when-creating-a-simple-d... 

Carol Gitonga, Developer Advocacy and Support, ADN Open
0 Likes
Message 5 of 8

BBKENGJS
Contributor
Contributor

I follow the topic on the forum for some time but I can't find answer to my problem. Even the samples provided by Autodesk dev team are not updated to the Revit2023 and they do not work. If anyone have simple example of working and tested VB.NET Revit 2023 API cod which can do successfully the following task:

Add dimensions to all edges in selected face of wall? Please share.   

0 Likes
Message 6 of 8

TripleM-Dev.net
Advisor
Advisor
Accepted solution

Hi,

I don't think it can be done like that, normally I would get the geometry and filter out the faces of the object that can be dimensioned (calculate against view's direction).

 

But try this: (lacks some checks and can fail in certain conditions, depending selected face/object)

It will dimension all edges of the selected face and places the dimension on the edge, not tested in R2023

 

Dim _doc As Document = _uiDoc.Document

			Dim r As Reference = _uiDoc.Selection.PickObject(ObjectType.Face, "Select a face")
			Dim e As Element = _uiDoc.Document.GetElement(r)
			Dim view As View = _uiDoc.ActiveView
			Dim oFace As Face = CType(e.GetGeometryObjectFromReference(r), Face)
			Dim edges As EdgeArray = CType(oFace.EdgeLoops(0), EdgeArray)

			'Limit the collection to Linear types.
			Dim dimensionStyle As DimensionType =
				New FilteredElementCollector(view.Document).WhereElementIsElementType.OfType(Of DimensionType).Where(Function(d) d.StyleType = DimensionStyleType.Linear).LastOrDefault

			Dim opt As Options = _uiDoc.Application.Application.Create.NewGeometryOptions
			opt.ComputeReferences = True 'Allow to compute references for dimensioning

			Dim FaceStableref As String = r.ConvertToStableRepresentation(_doc) 'to compare face against all faces of object
			Dim geo As GeometryElement = e.Geometry(opt) 'get all geometry
			Dim geoFace As PlanarFace = Nothing 'limit to PlanarFace

			For Each obj As GeometryObject In geo 'loop geometry
				If TypeOf (obj) Is Solid Then
					Dim sol As Solid = CType(obj, Solid)
					For Each Sface As Face In sol.Faces
						If TypeOf (Sface) Is PlanarFace Then
							If Sface.Reference.ConvertToStableRepresentation(_doc) = FaceStableref Then 'Compare Reference if it's the selected face, if so exit 
								geoFace = CType(Sface, PlanarFace)
								Exit For
							End If
						End If
					Next
				End If
				If Not (IsNothing(geoFace)) Then Exit For
			Next

			If TypeOf (geoFace) Is PlanarFace Then

				Using trans As New Transaction(_doc, "Add Wall Dimensions")
					trans.Start()
					For Each fEdges As EdgeArray In geoFace.EdgeLoops
						For Each fedge As Edge In fEdges

							Dim refArray As ReferenceArray = New ReferenceArray()
							refArray.Append(fedge.GetEndPointReference(0))
							refArray.Append(fedge.GetEndPointReference(1))
							Dim _dimline As Line = Line.CreateBound(fedge.AsCurve.GetEndPoint(0), fedge.AsCurve.GetEndPoint(1))
							Dim dimRef As Dimension = _doc.Create.NewDimension(view, _dimline, refArray, dimensionStyle)
						Next
					Next

					trans.Commit()
				End Using

			End If

 

- Michel

0 Likes
Message 7 of 8

BBKENGJS
Contributor
Contributor

I tested Yours cod in Revit 2023 and is working great. Thank You so much. I added the possibility to set the offset for the dimension line. However I'm working on project with many assembly views so the offset is showing correctly on eg. elevation but not on a plan etc. I will have to switch manually the direction of  "offsetVector". Is the any way that the program automatically recognize the direction based on picked face? 

 

Public Sub AddDim()

Dim _doc As Document = _uiDoc.Document

Dim r As Reference = _uiDoc.Selection.PickObject(ObjectType.Face, "Select a face")
Dim e As Element = _uiDoc.Document.GetElement(r)
Dim view As View = _uiDoc.ActiveView
Dim oFace As Face = CType(e.GetGeometryObjectFromReference(r), Face)
Dim edges As EdgeArray = CType(oFace.EdgeLoops(0), EdgeArray)

'Limit the collection to Linear types.
Dim dimensionStyle As DimensionType =
New FilteredElementCollector(view.Document).WhereElementIsElementType.OfType(Of DimensionType).Where(Function(d) d.StyleType = DimensionStyleType.Linear).LastOrDefault

Dim opt As Options = _uiDoc.Application.Application.Create.NewGeometryOptions
opt.ComputeReferences = True 'Allow to compute references for dimensioning

Dim FaceStableref As String = r.ConvertToStableRepresentation(_doc) 'to compare face against all faces of object
Dim geo As GeometryElement = e.Geometry(opt) 'get all geometry
Dim geoFace As PlanarFace = Nothing 'limit to PlanarFace

Dim offsetDistance As Double = -2

For Each obj As GeometryObject In geo 'loop geometry
If TypeOf (obj) Is Solid Then
Dim sol As Solid = CType(obj, Solid)
For Each Sface As Face In sol.Faces
If TypeOf (Sface) Is PlanarFace Then
If Sface.Reference.ConvertToStableRepresentation(_doc) = FaceStableref Then 'Compare Reference if it's the selected face, if so exit
geoFace = CType(Sface, PlanarFace)
Exit For
End If
End If
Next
End If
If Not (IsNothing(geoFace)) Then Exit For
Next

If TypeOf (geoFace) Is PlanarFace Then

Using trans As New Transaction(_doc, "Add Wall Dimensions")
trans.Start()
For Each fEdges As EdgeArray In geoFace.EdgeLoops
For Each fedge As Edge In fEdges

Dim curve As Curve = fedge.AsCurve 'get edge curve
Dim startPoint As XYZ = curve.GetEndPoint(0)
Dim endPoint As XYZ = curve.GetEndPoint(1)

'calculate offset vector
Dim direction As XYZ = (endPoint - startPoint).Normalize
Dim offsetVector As XYZ = direction.CrossProduct(XYZ.BasisY).Normalize * offsetDistance

'create offset start and end points
Dim offsetStartPoint As XYZ = startPoint + offsetVector
Dim offsetEndPoint As XYZ = endPoint + offsetVector

'create new line with offset points
Dim offsetLine As Line = Line.CreateBound(offsetStartPoint, offsetEndPoint)
Dim refArray As ReferenceArray = New ReferenceArray()
refArray.Append(fedge.GetEndPointReference(0))
refArray.Append(fedge.GetEndPointReference(1))
Dim _dimline As Line = Line.CreateBound(fedge.AsCurve.GetEndPoint(0), fedge.AsCurve.GetEndPoint(1))

' Dim dimRef As Dimension = _doc.Create.NewDimension(view, _dimline, refArray, dimensionStyle)
Dim dimRef As Dimension = _doc.Create.NewDimension(view, offsetLine, refArray, dimensionStyle)

Next
Next
trans.Commit()
End Using

End If

End Sub

0 Likes
Message 8 of 8

babatop489
Community Visitor
Community Visitor

 

In your code, you're trying to create a linear dimension with the following line:

 

vbCopy code
Dim dimRef As Dimension = _doc.Create.NewDimension(view, eline, refArray, dimensionStyle)

 

 

It seems like you are attempting to create a linear dimension based on the edge's curve (line). However, the error may be because the line may not be recognized as a linear curve by the New Dimension method.

To troubleshoot this issue, you can explicitly check if the edge's curve is linear before creating the dimension. Here's a modification to your code that includes such a check:

 

vbCopy code
If TypeOf eline Is Line Then Dim line As Line = CType(eline, Line) Dim dimRef As Dimension = _doc.Create.NewDimension(view, line, referral, dimension style) Else ' Handle non-linear curves or other cases ' You may want to add additional logic or message for non-linear elements End If
 

This modification checks if the curve is a Line before creating the dimension. If it's not a line, you might want to add additional logic to handle non-linear curves or choose an appropriate dimension type for non-linear elements.

If the issue persists, you may also want to double-check the dimension style variable to ensure that it corresponds to a linear dimension type and that it is properly retrieved from the document. You have already added a message box to display the dimension style's name, so make sure it's the correct type for linear dimensions. femfounder

0 Likes