Hi Jhoel,
Thanks a lot for the code - does the job more fast and you can watch the progress while running.
Before I used that code:
Imports ioPath = System.IO.Path
Imports System.Windows.Forms
Imports System.IO
Sub Main
'break
Dim ThisDoc As Inventor.Document = ThisApplication.ActiveDocument
Dim oDef As AssemblyComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition
'Get File Name of Assembly
Dim sAssFullFileName As String = ThisDoc.FullFileName
Dim sAssDirectoryName As String = ioPath.GetDirectoryName(ThisDoc.FullFileName)
Dim sAssFileNameWithoutExtension As String = ioPath.GetFileNameWithoutExtension(ThisDoc.FullFileName)
Dim BaseFileName As String = ioPath.Combine(sAssDirectoryName & sAssFileNameWithoutExtension)
' Der Export-Folder
Dim sExportFolder As String = String.Empty
Dim fbd As New FolderBrowserDialog
fbd.SelectedPath = sAssDirectoryName
If Not (fbd.ShowDialog() = DialogResult.OK) Then
Exit Sub
End If
sExportFolder = fbd.SelectedPath
' Get Reference BIM Component
Dim oBIM As BIMComponent = Nothing
Dim oBIMOC As BIMComponentPropertySet = Nothing
Dim iExportTotal As Integer = oDef.Occurrences.Count
Dim iCurrentExport As Integer = 1
Dim oProgBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, iExportTotal, "SSI BIM Export")
oProgBar.Message = "Export in progress " & iCurrentExport & " of " & iExportTotal
' Ein temporärer Ordner wird angelegt
Dim sTempFolder As String = createRandomTempFolder
Dim sTempAssemblyFileName As String
Dim oTempAssembly As Inventor.AssemblyDocument
'Dim oDocTemp As Inventor.Document
Dim oDocTemp As Inventor.PartDocument
'Break
' Alle Dateien in dem Zielordner werden gelöscht
'Directory.Delete(sExportFolder, )
For Each file As String In System.IO.Directory.GetFiles(sExportFolder)
System.IO.File.Delete(File)
Next
' Die .csv Datei
Dim sCVS As String = sExportFolder & "\instances.csv"
' Die .log Datei
Dim sLOG As String = sExportFolder & "\instances.log"
Dim assOccs = From occ As ComponentOccurrence In oDef.Occurrences _
Where occ.Suppressed = False _
Select occ
' Schleife über alle Occurences
For Each occ As ComponentOccurrence In assOccs
' For Each occ As ComponentOccurrence In oDef.Occurrences
'If TypeOf occ.Definition Is ComponentOccurrence Then
oProgBar.Message = "Export in progress " & iCurrentExport & " of " & iExportTotal
iCurrentExport += 1
' If Not occ.Suppressed Then
' Das zugehörige Document
Dim oDoc As Inventor.Document = occ.Definition.Document
' Die Matrix des gewählten Bauteils
Dim mat As Matrix = occ.Transformation
If oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject Then
'If True Then
'designPropSet = oDoc.PropertySets.Item("Design Tracking Properties")
Dim sPartNumber As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value
' Es kann vorkommen, dass die Bauteilnummer leer ist, dann wird stattdessen der Displayname verwendet
If sPartNumber.Equals(String.Empty) Then
sPartNumber = oDoc.DisplayName
End If
sPartNumber = sPartNumber.Replace(",", ".")
' Die .log Datei bekommt einen Eintrag
My.Computer.FileSystem.WriteAllText(sLOG, Replace(occ.Name, ":", "_") & "," & sPartNumber & vbCrLf, True)
' Es wird ein temporärer Name gebildet
'sTempFileName = ioPath.Combine(sTempFolder, designPropSet.Item("Part Number").Value & ioPath.GetExtension(oDoc.FullFileName))
sTempAssemblyFileName = ioPath.Combine(sTempFolder, Replace(occ.Name, ":", "_") & ".iam")
'oTempAssembly = CreateTempAssembly(ThisApplication, sTempAssemblyFileName)
'oTempAssembly = ThisApplication.Documents.Add(DocumentTypeEnum.kAssemblyDocumentObject, ThisApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kAssemblyDocumentObject))
Try
System.IO.File.Copy(ThisApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kAssemblyDocumentObject), sTempAssemblyFileName, True)
Catch
MsgBox("Failed to create temp copy of file:" & vbCrLf & sTempAssemblyFileName)
End Try
' Der Schreibschutz wird entfernt
System.IO.File.SetAttributes(sTempAssemblyFileName, FileAttributes.Normal)
' Die temporäre Baugruppe wird geöffnet
'oTempAssembly.Open
oTempAssembly = ThisApplication.Documents.Open(sTempAssemblyFileName, False)
' Das Bauteil wird platziert
Dim oCompOccPart As ComponentOccurrence = oTempAssembly.ComponentDefinition.Occurrences.Add(oDoc.FullFileName, mat)
oBIM = oTempAssembly.ComponentDefinition.BIMComponent
Dim oBimConnectors As BIMConnectors = oBIM.Connectors
' Alle Connectoren werden übertragen
Dim oBimConn As BIMConnector
Dim oBimConnDef As BIMConnectorDefinition
Dim oBimConnDefNew As BIMConnectorDefinition
Dim collGeo As ObjectCollection
' Schleife über alle Konnektoren
For i As Integer = 1 To oDoc.ComponentDefinition.BIMComponent.Connectors.count
oBimConn = oDoc.ComponentDefinition.BIMComponent.Connectors.Item(i)
oBimConnDef = oBimConn.Definition
collGeo = ThisApplication.TransientObjects.CreateObjectCollection
Dim oObj As Object
For j As Integer = 1 To oBimConnDef.Geometry.count
'oGeo = oBimConnDef.Geometry.Item(j)
'oObj = getGeometryByTransientKey(oCompOccPart.Definition, oBimConnDef.Geometry.Item(j).TransientKey)
'collGeo.Add(oObj)
oCompOccPart.CreateGeometryProxy(oBimConnDef.Geometry.Item(j), oObj)
collGeo.Add(oObj)
Next
'oBimConnDef.Geometry.Item(1).Edges(1).Geometry
Select oBimConn.DefinitionType
' Case BIMConnectorDefinitionTypeEnum.kBIMCableTrayConnectorType
' Case BIMConnectorDefinitionTypeEnum.kBIMConduitConnectorType
Case BIMConnectorDefinitionTypeEnum.kBIMDuctConnectorType
oBimConnDefNew = oBIM.Connectors.CreateDuctConnectorDefinition(collGeo, oBimConnDef.ConnectorShape)
oBimConnDefNew.Description = oBimConnDef.Description
'oBimConnDefNew.Direction = oBimConnDef.Direction
'oBimConnDefNew.ExposeDescriptionAsParameter = oBimConnDef.ExposeDescriptionAsParameter
'oBimConnDefNew.ExposeFlowValueAsParameter = oBimConnDef.ExposeFlowValueAsParameter
oBimConnDefNew.SystemType = oBimConnDef.SystemType
oBimConnDefNew.FlowConfiguration = oBimConnDef.FlowConfiguration
oBimConnDefNew.FlowDirection = oBimConnDef.FlowDirection
oBimConnDefNew.FlowValue = oBimConnDef.FlowValue
' Case BIMConnectorDefinitionTypeEnum.kBIMElectricalConnectorType
Case BIMConnectorDefinitionTypeEnum.kBIMPipeConnectorType
oBimConnDefNew = oBIM.Connectors.CreatePipeConnectorDefinition(collGeo, oBimConnDef.ConnectorShape)
Case Else
MsgBox("Connectortype not handled - " & oBimConn.DefinitionType.toString)
End Select
oBimConnectors.Add(oBimConnDefNew)
Next
' Write Component Type Definition
' If this line isn't run, the Model Properties tickbox will not get ticked and Model Properties will not get exported
oBIM.ComponentDescription.ComponentType = "23.40.70.11.11.14"
oBIM.ComponentDescription.FamilyType = sPartNumber
'oBIM.ComponentDescription.OrientationType = 103681
'Dim oBIMOrientType As BIMComponentOrientationTypeEnum = kUserCoordinateSystemOrientationType
oBIM.ComponentDescription.OrientationType = BIMComponentOrientationTypeEnum.kModelOriginOrientationType' 103683 '103681 = ViewCube, 103683 = UCS, 103682 = Model Origin
' oBIM.ComponentDescription.UserCoordinateSystemOrientation = oUCS
' Get reference for writting Identity Data
' Achtung: Hier muss der InternalName verwendet werden, da es sonst, je nach Inventor-Sprachversion, unterschiedliche Bezeichnungen gibt
oBIMOC = oBIM.ComponentDescription.ComponentPropertySets.Item("identity_data")
' Dim BIMDescProp As BIMComponentProperty
Dim BIMManProp As BIMComponentProperty
BIMManProp = oBIMOC.Item(1)
BIMManProp.Value = "SSI Test 123"
BIMManProp.Value = sPartNumber
' Dim oNameValueMap As NameValueMap
' oNameValueMap = ThisApplication.TransientObjects.CreateNameValueMap
' oNameValueMap.Add("RevitFileVersion", "Current")'Supported Revit File Version ("Current" = RFA2020, "Legacy" = RFA2017)
' oNameValueMap.Add(“CustomRevitFamilyTemplate”, pRFT)'Supported Revit Template (Generic *.rft options included with Inventor install)
' 'Export the file
' oBIMComp.ExportBuildingComponentWithOptions(BaseFileName & ".rfa", oNameValueMap) ’Can also use “.adsk” If required.
' ' Add custom properties ===========================
Dim oc As ObjectCollection = oBIM.ComponentDescription.ModelProperties
oc.Clear
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyText1", "CustomValue1"))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyText2", "CustomValue2"))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyText3", "CustomValue3"))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyNumber1", 1004))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyNumber2", 1005))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyNumber3", 1006))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyBoolean1", True))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyBoolean2", False))
oc.Add(SetCustomProperty(oTempAssembly, "CustomPropertyBoolean3", True))
Dim oCustProp As Inventor.Property
oCustProp = GetCustomProperty(oDoc, "DocNumber")
If oCustProp IsNot Nothing Then
oCustProp.Value = IIf (oCustProp.Value = String.Empty, "---", oCustProp.Value)
oc.Add(SetCustomProperty(oTempAssembly, "DocNumber", oCustProp.Value))
End If
oCustProp = GetCustomProperty(oDoc, "Z-Number")
If oCustProp IsNot Nothing Then
oCustProp.Value = IIf (oCustProp.Value = String.Empty, "---", oCustProp.Value)
oc.Add(SetCustomProperty(oTempAssembly, "Z-Number", oCustProp.Value))
End If
oCustProp = GetCustomProperty(oDoc, "Itemnumber")
If oCustProp IsNot Nothing Then
oCustProp.Value = IIf (oCustProp.Value = String.Empty, "---", oCustProp.Value)
oc.Add(SetCustomProperty(oTempAssembly, "Itemnumber", oCustProp.Value))
End If
oBIM.ComponentDescription.ModelProperties = oc
' ' Add custom properties ===========================
' Export .rfa file
oBIM.ExportBuildingComponent(ioPath.Combine(sExportFolder, Replace(occ.Name, ":", "_") & ".rfa")) 'By Part Number
' Die .csv Datei bekommt einen Eintrag
My.Computer.FileSystem.WriteAllText(sCVS, Replace(occ.Name, ":", "_") & "," & sPartNumber & ",0,0,0,0" & vbCrLf, True)
oProgBar.UpdateProgress
oTempAssembly.Save
oTempAssembly.Close
End If
Next
oProgBar.Close
End Sub
Function getGeometryByTransientKey(oCompDef As ComponentDefinition, iKey As Integer) As Object
Dim oObj As Object
For Each oBody As SurfaceBody In oCompDef.SurfaceBodies
oObj = oBody.BindTransientKeyToObject(iKey)
If oObj IsNot Nothing Then
Return oObj
End If
Next
Return Nothing
End Function
Function GetCustomProperty(oDoc As Inventor.Document, sPropertyName As String) As Inventor.Property
Dim oCustPropSet As PropertySet = oDoc.PropertySets.Item("Inventor User Defined Properties")
' Schleife über alle Custom-Porperties
Dim oProp As Inventor.Property
Dim bFound As Boolean = False
For i As Integer = 1 To oCustPropSet.Count
oProp = oCustPropSet.Item(i)
' Wenn der Name dem Gesuchten entspricht...
If oProp.Name.Equals(sPropertyName, StringComparison.OrdinalIgnoreCase) Then
' Merker, dass die Eigenschaft gefunden wurde
Return oProp
End If
Next
Return Nothing
End Function
Function SetCustomProperty(oDoc As Inventor.Document, sPropertyName As String, Value As Object) As Inventor.Property
Dim oCustPropSet As PropertySet = oDoc.PropertySets.Item("Inventor User Defined Properties")
' Schleife über alle Custom-Porperties
Dim oProp As Inventor.Property
Dim bFound As Boolean = False
For i As Integer = 1 To oCustPropSet.Count
oProp = oCustPropSet.Item(i)
' Wenn der Name dem Gesuchten entspricht...
If oProp.Name.Equals(sPopertyName, StringComparison.OrdinalIgnoreCase) Then
' Merker, dass die Eigenschaft gefunden wurde
bFound = True
Exit For
End If
Next
' Wenn die benutzerdefinierte Eigenschaft nicht gefunden wurde ...
If Not bFound Then
' ... wir die neue Eigenschaft angelegt
oProp = oCustPropSet.Add(Value, sPropertyName)
End If
' der Wert gesetzt
'oProp.Value = sValue
Return oProp
End Function
Private Function CreateTempAssembly(oApp As Inventor.Application, sAsmPathAndName As String) As AssemblyDocument
'Dim oApp As Application = ThisApplication
Dim oAssyDoc As Inventor.AssemblyDocument = oApp.Documents.Add(DocumentTypeEnum.kAssemblyDocumentObject, sAsmPathAndName)
Return oAssyDoc
End Function
Sub RotateAroundX(oMatrix As Matrix, rotationAngle As Double)
Dim oRotateMatrix As Matrix = ThisApplication.TransientGeometry.CreateMatrix
oRotateMatrix.Cell(1, 1) = 1
oRotateMatrix.Cell(1, 2) = 0
oRotateMatrix.Cell(1, 3) = 0
oRotateMatrix.Cell(2, 1) = 0
oRotateMatrix.Cell(2, 2) = Math.Cos(rotationAngle)
oRotateMatrix.Cell(2, 3) = -Math.Sin(rotationAngle)
oRotateMatrix.Cell(3, 1) = 0
oRotateMatrix.Cell(3, 2) = Math.Sin(rotationAngle)
oRotateMatrix.Cell(3, 3) = Math.Cos(rotationAngle)
oMatrix.TransformBy(oRotateMatrix)
End Sub
Sub RotateAroundY(oMatrix As Matrix, rotationAngle As Double)
Dim oRotateMatrix As Matrix = ThisApplication.TransientGeometry.CreateMatrix
oRotateMatrix.Cell(1, 1) = Math.Cos(rotationAngle)
oRotateMatrix.Cell(1, 2) = 0
oRotateMatrix.Cell(1, 3) = Math.Sin(rotationAngle)
oRotateMatrix.Cell(2, 1) = 0
oRotateMatrix.Cell(2, 2) = 1
oRotateMatrix.Cell(2, 3) = 0
oRotateMatrix.Cell(3, 1) = -Math.Sin(rotationAngle)
oRotateMatrix.Cell(3, 2) = 0
oRotateMatrix.Cell(3, 3) = Math.Cos(rotationAngle)
oMatrix.TransformBy(oRotateMatrix)
End Sub
Sub RotateAroundZ(oMatrix As Inventor.Matrix, rotationAngle As Double)
Dim oRotateMatrix As Matrix = ThisApplication.TransientGeometry.CreateMatrix
oRotateMatrix.Cell(1, 1) = Math.Cos(rotationAngle)
oRotateMatrix.Cell(1, 2) = -Math.Sin(rotationAngle)
oRotateMatrix.Cell(1, 3) = 0
oRotateMatrix.Cell(2, 1) = Math.Sin(rotationAngle)
oRotateMatrix.Cell(2, 2) = Math.Cos(rotationAngle)
oRotateMatrix.Cell(2, 3) = 0
oRotateMatrix.Cell(3, 1) = 0
oRotateMatrix.Cell(3, 2) = 0
oRotateMatrix.Cell(3, 3) = 1
oMatrix.TransformBy(oRotateMatrix)
End Sub
Sub exportOccurences(sExportFolder As String)
Dim sExportOccurencePositions As String = ioPath.Combine(sExportFolder & "positions.xml")
'MsgBox(sExportFolder)
End Sub
Function createRandomTempFolder() As String
Dim folder As String = ioPath.Combine(ioPath.GetTempPath, ioPath.GetFileNameWithoutExtension(ioPath.GetRandomFileName))
Do While System.IO.Directory.Exists(folder) Or System.IO.File.Exists(folder)
folder = ioPath.Combine(ioPath.GetTempPath, ioPath.GetFileNameWithoutExtension(ioPath.GetRandomFileName))
Loop
If Not System.IO.Directory.Exists(folder) Then
System.IO.Directory.CreateDirectory(folder)
End If
Return folder
End Function
' https://www.startbim.com/2017/06/omniclass-23-products-list.html
' [Design Data]\BIM Exchange\Support\AuthoringTemplates\Categories.xml
Public NotInheritable Class Omniclass
Public Const ManufacturingEquipment As String = "23.40.70.17.11"
Public Const Conveyor As String = "23.50.30.24"
Public Const HVAC As String = "23.75.00.00"
' ...
End Class
' 'summaryPropSet = oDoc.PropertySets.Item("Inventor Summary Information")
' customPropSet = oDoc.PropertySets.Item("Inventor User Defined Properties")
' designPropSet = oDoc.PropertySets.Item("Design Tracking Properties")
' pDesc = designPropSet.Item("Description")
' pPart = designPropSet.Item("Part Number")
' pVend = designPropSet.Item("Vendor")
' 'Set Properties
' Description = pDesc.Value
' PartNumber = pPart.Value
' Manufacturer = pVend.Value
' Model = Left(oDoc.FullFileName, Len(oDoc.FullFileName) - 4)
' URL = "www.autodesk.com"
' 'MessageBox.Show("Property = " & Description, "Parameter Read Validation")
' 'Check for existing exported file
' CurrentFile = FolderName & PartNumber & ".adsk"
' If System.IO.File.Exists(CurrentFile) Then
' 'MessageBox.Show("The file already exists.")
' Else
' 'Set the Revit Family Component Type
' If familyType = "Conveyor" Then
' ComponentType = "23.50.30.24"
' ElseIf familyType = "HVAC" Then
' ComponentType = "23.75.00.00"
' Else 'Everything else will be defined as Manufacturing Equipment
' ComponentType = "23.40.70.17.11"
' End If
' 'Get Reference BIM Component
' Dim oBIM As BIMComponent
' oBIM = oDoc.ComponentDefinition.BIMComponent
' 'Write Component Type Definition
' 'If this line isn't run, the Model Properties tickbox will not get ticked and Model Properties will not get exported
' oBIM.ComponentDescription.ComponentType = ComponentType
' 'Set Export Orientation (ViewCube, Model Origin)
' oBIM.ComponentDescription.OrientationType = 103682 '103681 = ViewCube, 103683 = UCS, 103682 = Model Origin
' 'Get reference for writting Identity Data
' Dim oBimOC As BIMComponentPropertySet
' oBimOC = oBIM.ComponentDescription.ComponentPropertySets.Item("Identity Data")
' 'Write BIM Identity data
' 'This must be set after 'Write Component Type Definition' otherwise this data will get wiped
' Dim BIMDescProp As BIMComponentProperty
' Dim BIMManProp As BIMComponentProperty
' Dim BIMModelProp As BIMComponentProperty
' Dim BIMURLProp As BIMComponentProperty
' BIMDescProp = oBimOC.Item(1)
' BIMDescProp.Value = Description
' BIMManProp = oBimOC.Item(2)
' BIMManProp.Value = Manufacturer
' BIMModelProp = oBimOC.Item(3)
' BIMModelProp.Value = Model
' BIMURLProp = oBimOC.Item(4)
' BIMURLProp.Value = URL
' 'Export .adsk file
' 'oBIM.ExportBuildingComponent(oDoc.FullFileName & ".adsk") 'Includes Inventor file extension
' 'oBIM.ExportBuildingComponent(FolderName & Left(oDoc.FullFileName, Len(oDoc.FullFileName) - 4) & ".adsk") 'By Occurence Filename
' oBIM.ExportBuildingComponent(FolderName & PartNumber & ".adsk") 'By Part Number
' FileExists = False
' End If
'Next
This code is also fine but doesn´t go through the sub-assemblies - writing RFAs only on first level.
Could this 2 codes be combined to run through all occurences?