Add dimensions to assembly in Revit 2023 API

Add dimensions to assembly in Revit 2023 API

BBKENGJS
Contributor Contributor
685 Views
9 Replies
Message 1 of 10

Add dimensions to assembly in Revit 2023 API

BBKENGJS
Contributor
Contributor

I'm getting Error in Revit 2023:
"Object reference not set to an instance of an object."
Haw to fix the code?

 

 

<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)>
Public Class AddDimToAssemblies
Implements Autodesk.Revit.UI.IExternalCommand
Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute

Dim uidoc As UIDocument = commandData.Application.ActiveUIDocument
Dim doc As Document = uidoc.Document
Dim assemblies As List(Of Element) = New FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Assemblies).WhereElementIsNotElementType().ToList()
Dim lineReference As Line = Nothing

Try
Using tx As Transaction = New Transaction(doc, "Add Dimensions to Assemblies")
tx.Start()

For Each assembly As Element In assemblies
Dim assemblyGeometry As GeometryElement = assembly.Geometry(New Options())
Dim assemblyBoundingBox As BoundingBoxXYZ = assemblyGeometry.GetBoundingBox()

Dim referenceArray As ReferenceArray = New ReferenceArray()

For Each edge As Edge In assemblyGeometry.OfType(Of Edge)()
Dim curve As Curve = edge.AsCurve()
Dim line As Line = TryCast(curve, Line)
If line IsNot Nothing Then
Dim startPoint As XYZ = line.GetEndPoint(0)
Dim endPoint As XYZ = line.GetEndPoint(1)
lineReference = Line.CreateBound(startPoint, endPoint)
referenceArray.Append(lineReference.Reference)
End If
Next

If uidoc.ActiveView IsNot Nothing AndAlso referenceArray.Size > 0 AndAlso lineReference IsNot Nothing Then
Dim dimension As Dimension = doc.Create.NewDimension(uidoc.ActiveView, lineReference, referenceArray)
dimension.ValueOverride = assemblyBoundingBox.Max.Z - assemblyBoundingBox.Min.Z
End If
Next

tx.Commit()
End Using

Catch ex As Exception
message = ex.Message
Return Autodesk.Revit.UI.Result.Failed
End Try

Return Result.Succeeded
End Function

End Class

0 Likes
686 Views
9 Replies
Replies (9)
Message 2 of 10

moturi.magati.george
Autodesk
Autodesk

Hi @BBKENGJS,

 

You need to check if assemblyGeometry is null first before getting the Bounding Box.

 

Hope this helps.

 

  Moturi George,     Developer Advocacy and Support,  ADN Open
0 Likes
Message 3 of 10

BBKENGJS
Contributor
Contributor

I modified the cod as below but still getting errors in AddDimensionsToView

Can someone help me to fix the code?

 

<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)>
Public Class AddDimToAssemblies
Implements Autodesk.Revit.UI.IExternalCommand
Dim _uiApp As UIApplication
Dim _uiDoc As UIDocument


Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute

Dim uiApp As UIApplication = commandData.Application
Dim uiDoc As UIDocument = uiApp.ActiveUIDocument
Dim doc As Document = uiDoc.Document

' Select an assembly instance in Revit
Dim assemblyInstance As AssemblyInstance = SelectAssemblyInstance(uiDoc)

' Get the active view
Dim activeView As View = doc.ActiveView

' Get the geometry of the assembly instance
Dim assemblyGeometry As GeometryElement = assemblyInstance.Geometry(New Options())

' Define the offset of the dimensions from the assembly geometry edge
Dim offset As Double = GetUserOffset()

' Add dimensions to the assembly in the active view

AddDimensionsToView(activeView, assemblyGeometry, offset)

Return Result.Succeeded

End Function

Private Function SelectAssemblyInstance(uiDoc As UIDocument) As AssemblyInstance

' Create a reference to pick an element in Revit
Dim ref As Reference = uiDoc.Selection.PickObject(ObjectType.Element, "Select an assembly instance")

' Get the element from the reference
Dim elem As Element = uiDoc.Document.GetElement(ref)

' Check if the element is an assembly instance
If TypeOf elem Is AssemblyInstance Then
Return CType(elem, AssemblyInstance)
Else
Throw New Exception("Selected element is not an assembly instance")
End If

End Function

Private Function GetUserOffset() As Double

' Prompt the user for the offset distance
Dim offset As Double = 0
Dim result As Boolean = Double.TryParse(InputBox("Enter the offset distance for the dimensions:", "Offset Distance"), offset)

' Check if the user entered a valid number
If Not result Then
Throw New Exception("Invalid offset distance")
End If

Return offset

End Function

Private Sub AddDimensionsToView(view As View, geometry As GeometryElement, offset As Double)

' Create a dimension style for the dimensions
Dim dimensionStyle As DimensionType = New FilteredElementCollector(view.Document).OfClass(GetType(DimensionType)).Cast(Of DimensionType)().FirstOrDefault()

If dimensionStyle Is Nothing Then
Throw New Exception("No dimension style found in document")
End If

' Loop through the geometry of the assembly instance
For Each geomObj As GeometryObject In geometry
If TypeOf geomObj Is Solid Then
Dim solid As Solid = CType(geomObj, Solid)

' Loop through the edges of the solid
For Each edge As Edge In solid.Edges
Dim curve As Curve = edge.AsCurve()

' Create a dimension line for the edge
Dim dimensionLine As Line = curve.CreateOffset(offset, view.ViewDirection)
Dim dimensionPlane As Plane = Plane.CreateByNormalAndOrigin(view.ViewDirection, dimensionLine.GetEndPoint(0))

' Create a dimension object between two reference points
Dim ref1 As Reference = edge.Reference
Dim ref2 As Reference = ref1 ' Use the same reference to create a linear dimension
Dim references As ReferenceArray = New ReferenceArray()
references.Append(ref1)
references.Append(ref2)

' Create a dimension curve between the two references
Dim dimensionCurve As Line = Line.CreateBound(ref1.GlobalPoint, ref2.GlobalPoint)

' Create the dimension

Dim dimension As Dimension = dimension.Create(view.Document, dimensionCurve, dimensionPlane, references, dimensionStyle.Id) 'ERROR

' Lock the dimension and add it to the view
dimension.IsLocked = True
view.AddElement(dimension) 'ERROR
Next
End If
Next
End Sub

End Class

Message 4 of 10

BBKENGJS
Contributor
Contributor

I'm still getting error in Revit 2023; "Object Reference not set to an instance of an object" 

Please help me to fix the code.

 

<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)>
Public Class AddDimToAssemblies
Implements Autodesk.Revit.UI.IExternalCommand


Private _uiApp As UIApplication
Private _uiDoc As UIDocument
Private _doc As Document


Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute
_uiApp = commandData.Application
_uiDoc = _uiApp.ActiveUIDocument
_doc = _uiDoc.Document

Using t As New Transaction(_doc, "Add dimensions to assemblies")
t.Start()
' Select an assembly instance in Revit
Dim assemblyInstance As AssemblyInstance = SelectAssemblyInstance(_uiDoc)

' Get the active view
Dim activeView As View = _doc.ActiveView

' Get the geometry of the assembly instance
Dim assemblyGeometry As GeometryElement = assemblyInstance.Geometry(New Options())

' Define the offset of the dimensions from the assembly geometry edge
Dim offset As Double = GetUserOffset()

' Add dimensions to the assembly in the active view

AddDimensionsToView(activeView, assemblyGeometry, offset)
t.Commit()
End Using
Return Result.Succeeded

End Function

Private Function SelectAssemblyInstance(_uiDoc As UIDocument) As AssemblyInstance

' Create a reference to pick an element in Revit
Dim ref As Reference = _uiDoc.Selection.PickObject(ObjectType.Element, "Select an assembly instance")

' Get the element from the reference
Dim elem As Element = _uiDoc.Document.GetElement(ref)
If elem Is Nothing Then
Throw New Exception("No assembly instance selected")
End If
' Check if the element is an assembly instance
If TypeOf elem Is AssemblyInstance Then
Return CType(elem, AssemblyInstance)
Else
Throw New Exception("Selected element is not an assembly instance")
End If

End Function

Private Function GetUserOffset() As Double

' Prompt the user for the offset distance
Dim offset As Double = 0
Dim result As Boolean = Double.TryParse(InputBox("Enter the offset distance for the dimensions:", "Offset Distance"), offset)

' Check if the user entered a valid number
If Not result Then
Throw New Exception("Invalid offset distance")
End If

Return offset

End Function

Private Sub AddDimensionsToView(view As View, geometry As GeometryElement, offset As Double)

' Create a dimension style for the dimensions
Dim dimensionStyle As DimensionType = New FilteredElementCollector(view.Document).OfClass(GetType(DimensionType)).Cast(Of DimensionType)().FirstOrDefault()
Try

 

If dimensionStyle Is Nothing Then
Throw New Exception("No dimension style found in document")
End If
MessageBox.Show(dimensionStyle.Name.ToString)
' Loop through the geometry of the assembly instance
For Each geomObj As GeometryObject In geometry
If TypeOf geomObj Is Solid Then
Dim solid As Solid = CType(geomObj, Solid)

' Loop through the edges of the solid
For Each edge As Edge In solid.Edges
Dim curve As Curve = edge.AsCurve()
'view = _doc.ActiveView

' Create a dimension line for the edge
Dim dimensionLine As Line = curve.CreateOffset(offset, view.ViewDirection)
Dim dimensionPlane As Plane = Plane.CreateByNormalAndOrigin(view.ViewDirection, dimensionLine.GetEndPoint(0))

' Create a dimension object between two reference points
Dim ref1 As Reference = edge.Reference
Dim ref2 As Reference = ref1 ' Use the same reference to create a linear dimension
Dim references As ReferenceArray = New ReferenceArray()
references.Append(ref1)
references.Append(ref2)

' Create a dimension curve between the two references
Dim dimensionCurve As Line = Line.CreateBound(ref1.GlobalPoint, ref2.GlobalPoint)

' Create the dimension
If _doc Is Nothing Then
Throw New Exception("Document is not initialized")
End If

If view Is Nothing Then
Throw New Exception("View is not initialized")
End If
Dim dimension As Dimension = _doc.Create.NewDimension(view, dimensionCurve, references, dimensionStyle)

' Lock the dimension and add it to the view
dimension.IsLocked = True
' view.AddElement(dimension) 'ERROR


Next
End If
Next

Catch e As Exception
MessageBox.Show(e.Message)

End Try
End Sub

End Class

Public Class AssemblyInstanceSelectionFilter
Implements ISelectionFilter

Public Function AllowElement(ByVal element As Element) As Boolean Implements ISelectionFilter.AllowElement
Return TypeOf element Is AssemblyInstance
End Function

Public Function AllowReference(ByVal reference As Reference, ByVal position As XYZ) As Boolean Implements ISelectionFilter.AllowReference
Return True
End Function

End Class

 

0 Likes
Message 5 of 10

moturi.magati.george
Autodesk
Autodesk

Hi @BBKENGJS,

 

Make sure you Revit project contains an assembly.

 

Revit Lookup tool comes in handy to snoop you project.

 

  Moturi George,     Developer Advocacy and Support,  ADN Open
0 Likes
Message 6 of 10

BBKENGJS
Contributor
Contributor

The project contains assembly. Using Revit 2023 API I'm rotating assembly origin, then create a sheet with assembly views and now I'm trying to add dimensions do the assembly...Any helpful suggestions haw to fix the code?  

Message 7 of 10

BBKENGJS
Contributor
Contributor

Here is short version but the problem is the same ERROR: "Revit encountered a object Reference not set to an instance of an object" in Revit 2023. Maybe someone knows how to fix? 

 

<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)>
Public Class AddDimToAssemblies
Implements Autodesk.Revit.UI.IExternalCommand
Private _uiApp As UIApplication
Private _uiDoc As UIDocument
Private _doc As Document
Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute
_uiApp = commandData.Application
_uiDoc = _uiApp.ActiveUIDocument
_doc = _uiDoc.Document

Using t As New Transaction(_doc, "Add dimensions to assemblies")
t.Start()
' Get the selected assembly instance
Dim selSet As Selection = _uiDoc.Selection
Dim selObj As Object = selSet.PickObject(ObjectType.Element, "Select an assembly instance")
'Dim asmInst As FamilyInstance = TryCast(_doc.GetElement(selObj.ElementId), FamilyInstance)
Dim asmInst As Wall = TryCast(_doc.GetElement(selObj.ElementId), Wall)
' Get the current view
Dim view As View = _uiDoc.ActiveView

Dim dimensionStyle As DimensionType = New FilteredElementCollector(view.Document).OfClass(GetType(DimensionType)).Cast(Of DimensionType)().FirstOrDefault()
If dimensionStyle Is Nothing Then
Throw New Exception("No dimension style found in document")
End If

' Get the edge references of the assembly instance
Dim edgeRefs As List(Of Reference) = New List(Of Reference)

 

Dim geomElem As GeometryElement = asmInst.Geometry(New Options()) 'ERROR: "Revit encountered a object Reference not set to an instance of an object"

If geomElem IsNot Nothing Then
For Each geomObj As GeometryObject In geomElem
Dim solid As Solid = TryCast(geomObj, Solid)
If solid IsNot Nothing Then
For Each edge As Edge In solid.Edges
Dim edgeRef As Reference = edge.Reference
edgeRefs.Add(edgeRef)
Next
End If
Next
Else
Throw New Exception("Invalid geometry for the selected assembly instance")
End If

' Add dimensions to the edges with the specified offset
Dim offset As Double = 0.1
Dim dimRefs As List(Of Dimension) = New List(Of Dimension)
For Each edgeRef As Reference In edgeRefs
Dim dimLine As Line = Line.CreateBound(edgeRef.GlobalPoint - offset * view.RightDirection, edgeRef.GlobalPoint + offset * view.RightDirection)
Dim refArray As ReferenceArray = New ReferenceArray()
refArray.Append(edgeRef)
Dim dimRef As Dimension = _doc.Create.NewDimension(view, dimLine, refArray, dimensionStyle)

dimRefs.Add(dimRef)
Next

' Select the dimensions for easier editing
selSet.SetElementIds(dimRefs.Select(Function(d) d.Id))

t.Commit()
End Using
Return Result.Succeeded

End Function

End Class

 

 

 

0 Likes
Message 8 of 10

Revitalizer
Advisor
Advisor

Hi,

 

you are creating a new Options object.

Make sure its ComputeReferences property is set to "true".

 

Dim assemblyGeometry As GeometryElement = assembly.Geometry(New Options())

 

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





0 Likes
Message 9 of 10

BBKENGJS
Contributor
Contributor

I added this but still the same Error in Revit: "Revit encountered a object Reference not set to an instance of an object" . If you know how to fix please help me.

 

<Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)>
Public Class AddDimToAssemblies
Implements Autodesk.Revit.UI.IExternalCommand
Private _uiApp As UIApplication
Private _uiDoc As UIDocument
Private _doc As Document
Public Function Execute(commandData As ExternalCommandData, ByRef message As String, elements As ElementSet) As Result Implements IExternalCommand.Execute
_uiApp = commandData.Application
_uiDoc = _uiApp.ActiveUIDocument
_doc = _uiDoc.Document

Using t As New Transaction(_doc, "Add dimensions to assemblies")
t.Start()
' Get the selected assembly instance
Dim selSet As Selection = _uiDoc.Selection
Dim selObj As Object = selSet.PickObject(ObjectType.Element, "Select an assembly instance")
'Dim asmInst As FamilyInstance = TryCast(_doc.GetElement(selObj.ElementId), FamilyInstance)
Dim asmInst As Wall = TryCast(_doc.GetElement(selObj.ElementId), Wall)
' Get the current view
Dim view As View = _uiDoc.ActiveView

Dim dimensionStyle As DimensionType = New FilteredElementCollector(view.Document).OfClass(GetType(DimensionType)).Cast(Of DimensionType)().FirstOrDefault()
If dimensionStyle Is Nothing Then
Throw New Exception("No dimension style found in document")
End If

' Get the edge references of the assembly instance
Dim edgeRefs As List(Of Reference) = New List(Of Reference)
Dim dimOptions As New Options
dimOptions.ComputeReferences = True

Dim geomElem As GeometryElement = asmInst.Geometry(dimOptions) 'ERROR: "Revit encountered a object Reference not set to an instance of an object"

If geomElem IsNot Nothing Then
For Each geomObj As GeometryObject In geomElem
Dim solid As Solid = TryCast(geomObj, Solid)
If solid IsNot Nothing Then
For Each edge As Edge In solid.Edges
Dim edgeRef As Reference = edge.Reference
edgeRefs.Add(edgeRef)
Next
End If
Next
Else
Throw New Exception("Invalid geometry for the selected assembly instance")
End If

' Add dimensions to the edges with the specified offset
Dim offset As Double = 0.1
Dim dimRefs As List(Of Dimension) = New List(Of Dimension)
For Each edgeRef As Reference In edgeRefs
Dim dimLine As Line = Line.CreateBound(edgeRef.GlobalPoint - offset * view.RightDirection, edgeRef.GlobalPoint + offset * view.RightDirection)
Dim refArray As ReferenceArray = New ReferenceArray()
refArray.Append(edgeRef)
Dim dimRef As Dimension = _doc.Create.NewDimension(view, dimLine, refArray, dimensionStyle)

dimRefs.Add(dimRef)
Next

' Select the dimensions for easier editing
selSet.SetElementIds(dimRefs.Select(Function(d) d.Id))

t.Commit()
End Using
Return Result.Succeeded

End Function

End Class

0 Likes
Message 10 of 10

sefa_guntepe
Explorer
Explorer

Hello, is there any progress on the issue? @BBKENGJS 

0 Likes