RFA Export

RFA Export

thomas.BaunachVVBHV
Participant Participant
3,633 Views
17 Replies
Message 1 of 18

RFA Export

thomas.BaunachVVBHV
Participant
Participant

Hi,

i´m looking for an iLogic-code to export all parts of an assembly (+ sub) as single rfa-files including her geometric position in relation to the top-assembly...

0 Likes
Accepted solutions (1)
3,634 Views
17 Replies
Replies (17)
Message 2 of 18

chandra.shekar.g
Autodesk Support
Autodesk Support

@thomas.BaunachVVBHV,

 

Unfortunately, Inventor application is not supported to export Inventor files into .rfa file. Please log a wish list at idea station using below link.

 

https://forums.autodesk.com/t5/inventor-ideas/idb-p/v1232

 

But there is a way to export into .adsk file format. For more details, go through below forum discussion link.

 

https://forums.autodesk.com/t5/inventor-customization/ilogic-bim-export-to-adsk/td-p/9146183

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 3 of 18

Anonymous
Not applicable

@chandra.shekar.gthat is not accurate, you have been able to export RFA files for several years now, see https://knowledge.autodesk.com/support/inventor-products/learn-explore/caas/CloudHelp/cloudhelp/2014...

 

What @thomas.BaunachVVBHV  is looking for is the iLogic code to export an RFA.

Message 4 of 18

thomas.BaunachVVBHV
Participant
Participant

Thank You Clint,

that´s exactly the Point...

I would need a code that goes through all components of all Sub-Assemblies and generate rfa-files for each - incl. component-position in relation to the top-assembly.

My plan is to build it up in Revit using a dynamo script...

0 Likes
Message 5 of 18

Anonymous
Not applicable

Hi @thomas.BaunachVVBHV .  Two years ago I was also looking for the same code for the same workflow. And its just now that I completed this. Anyway, I hope this will work for you.

 

Sub Main
Dim oDoc As Document
oDoc = ThisApplication.ActiveDocument
Dim oAsmDoc As AssemblyDocument
 oAsmDoc = ThisApplication.ActiveDocument
 
 If MsgBox("Do you want to continue?", vbOKCancel + vbExclamation, "Batch Create RFA") = vbCancel Then Exit Sub

   
    ' Get the assembly component definition.
    Dim oCompDef As AssemblyComponentDefinition
   	oCompDef = oAsmDoc.ComponentDefinition
   
    ' Get all of the leaf occurrences of the assembly.
    Dim oLeafOccs As ComponentOccurrencesEnumerator
    oLeafOccs = oCompDef.Occurrences.AllLeafOccurrences
   
    ' Iterate through the occurrences and print the name.
    Dim oOcc As ComponentOccurrence
    For Each oOcc In oLeafOccs
    	oOcc.Visible = False
    Next
	
	For Each oOcc In oLeafOccs
    	oOcc.Visible = False
		Dim oOccName As String = oOcc.Name.Replace(":", "_")
'		MsgBox(oOccName)
		
		Dim FullFileName As String = "C:\Users\Joseph\Desktop\Inventor Study\AL WASL\Workspaces\Workspace\Test\ToRFA\" & oOccName & ".rfa"
		oCompDef.BIMComponent.ExportBuildingComponent(FullFileName)
	
		oOcc.Visible = False
Next

    For Each oOcc In oLeafOccs
    	oOcc.Visible = True

Next


End Sub

	

Message 6 of 18

Anonymous
Not applicable
0 Likes
Message 7 of 18

thomas.BaunachVVBHV
Participant
Participant

Hi JOJO,

 

Thank You very much - will try this and see if it works for me....

0 Likes
Message 8 of 18

thomas.BaunachVVBHV
Participant
Participant

Hi JOJO,

 

i tried your code on several assemblies, but always hanging (with no response).

Can it be that there´s a problem with component-pattern and/or content center instances?

 

Thanks so far for your work

 

0 Likes
Message 9 of 18

Anonymous
Not applicable

Hi @thomas.BaunachVVBHV . Actually it is slow even with small assembly and to be honest I dont know why. Ill check if there is a way to make it faster. Just tested it with component-pattern, it works. 

0 Likes
Message 10 of 18

thomas.BaunachVVBHV
Participant
Participant

Hi JOJO,

 

thank you for your response - for my last attempt  i waited about 1 hour b4 i stopped....

In this assembly were only about 50 occurrences...

My problem is, that i want to use assemblies with more than 500 occurrences.

But anyway - many thanks for your time and your support

0 Likes
Message 11 of 18

lmc.engineering
Advocate
Advocate

Hi @thomas.BaunachVVBHV 

 

I have added a iLogic logger to the code so you can see the progress of your export. I wouldn't expect this to be quick as Inventor is doing a lot of translation work in the background. At least with this mod you can see where it's at as it's processing:

 

Sub Main
	Dim oDoc As Document
	oDoc = ThisApplication.ActiveDocument
	Dim oAsmDoc As AssemblyDocument
	oAsmDoc = ThisApplication.ActiveDocument

	If MsgBox("Do you want to continue?", vbOKCancel + vbExclamation, "Batch Create RFA") = vbCancel Then Exit Sub

	' Get the assembly component definition.
	Dim oCompDef As AssemblyComponentDefinition
	oCompDef = oAsmDoc.ComponentDefinition

	' Get all of the leaf occurrences of the assembly.
	Dim oLeafOccs As ComponentOccurrencesEnumerator
	oLeafOccs = oCompDef.Occurrences.AllLeafOccurrences

	' Iterate through the occurrences and print the name.
	Dim oOcc As ComponentOccurrence
	For Each oOcc In oLeafOccs
		oOcc.Visible = False
	Next

	Dim LeafCount As Integer = oLeafOccs.Count
	Dim i As Integer = 1
	For Each oOcc In oLeafOccs
		oOcc.Visible = False
		Dim oOccName As String = oOcc.Name.Replace(":", "_")
		'		MsgBox(oOccName)

		Dim FullFileName As String = "C:\temp\" & oOccName & ".rfa"
		Logger.Debug("Processing document " & i & " of " & LeafCount)
		Logger.Debug("Current Document name: " & oOccName)

		oCompDef.BIMComponent.ExportBuildingComponent(FullFileName)

		oOcc.Visible = False
		i += 1
	Next

	For Each oOcc In oLeafOccs
	oOcc.Visible = True
	Next
End Sub 

Don't forget to show your iLogic Log tab before you run this by pressing the '+' on your model browser.

Message 12 of 18

JhoelForshav
Mentor
Mentor

Hi @thomas.BaunachVVBHV 

As stated by @lmc.engineering, this will take time... I cleaned up the code a bit but I don't expect it to run much faster.

I also added a progressbar to it. Basically I use a different approach to hide and show all occurrences that I think will be faster. But the main thing thats time consuming is still the translation to RFA, and there's not much we can do about that...

Imports System.Windows.Forms
Sub Main
	Dim oDlg As New FolderBrowserDialog
	oDlg.Description = "Select folder to save RFA-files"
	oDlg.ShowDialog
	If oDlg.SelectedPath = "" Then Exit Sub
	Dim oPath As String = oDlg.SelectedPath
	Dim oAsmDoc As AssemblyDocument = ThisDoc.Document
	If MsgBox("Do you want to continue?", vbOKCancel + vbExclamation, "Batch Create RFA") = vbCancel Then Exit Sub
	Dim oCompDef As AssemblyComponentDefinition = oAsmDoc.ComponentDefinition
	Dim oLeafOccs As ComponentOccurrencesEnumerator = oCompDef.Occurrences.AllLeafOccurrences
	Dim oTotal As Integer = oLeafOccs.Count
	Dim oProgressBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, oTotal, "Exporting to RFA", False)
	ThisApplication.UserInterfaceManager.DoEvents
	oAsmDoc.ComponentDefinition.RepresentationsManager.ActiveDesignViewRepresentation.HideAll
	Dim oBIMcomponent As BIMComponent = oCompDef.BIMComponent
	Dim i As Integer = 1
	Dim oOcc As ComponentOccurrence
	For Each oOcc In oLeafOccs
		oOcc.Visible = True
		Dim oOccName As String = oOcc.Name.Replace(":", "_")
		Dim FullFileName As String = oPath & "\" & oOccName & ".rfa"
		oProgressBar.Message = "Exporting " & FullFileName & " (" & i & "/" & oTotal & ")"
		oProgressBar.UpdateProgress
		ThisApplication.UserInterfaceManager.DoEvents
		oBIMcomponent.ExportBuildingComponent(FullFileName)
		oOcc.Visible = False
		i += 1
	Next
	oProgressBar.Close
	oAsmDoc.ComponentDefinition.RepresentationsManager.ActiveDesignViewRepresentation.ShowAll
End Sub
Message 13 of 18

Anonymous
Not applicable

This is a lot faster and looks professional!  By the way, the reason why there is "vbExclamation" there is because its slow. Applying shrinkwrap could help. Thank you to all.

0 Likes
Message 14 of 18

thomas.BaunachVVBHV
Participant
Participant

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?

 

0 Likes
Message 15 of 18

JhoelForshav
Mentor
Mentor
Accepted solution

@Anonymous 

I'm glad to hear it's faster... I didn't really test it on a bigger assembly so I wouldn't know 🙂

Shrikwrap could be a way to reduce time for sure. But we'll have to take into account the time it would take to create the shrinkwraps 😉

 

@thomas.BaunachVVBHV 

Wow, that's a massive chunk of code! I'm glad to see it contains my subs for rotating a matrix from here:

https://forums.autodesk.com/t5/inventor-customization/ilogic-place-a-part-and-define-rotation/td-p/8983150

The subs are never used in the code though so they can just aswell be removed 🙂

To make it run through all parts, even in subassemblies, you can use ComponentOccurrences.AllLeafOccurrences, since parts are allways leaf occurrences. Just as @Anonymous did in his code.

I haven't gone through your code in detail but just changing from traversing ComponentOccurrences to traversing AllLeafOccurrences should do the trick:

Imports ioPath = System.IO.Path
Imports System.Windows.Forms
Imports System.IO
Sub Main

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.AllLeafOccurrences.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


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.AllLeafOccurrences _
Where occ.Suppressed = False _
Select occ

' Schleife über alle Occurences
For Each occ As ComponentOccurrence In assOccs

oProgBar.Message = "Export in progress " & iCurrentExport & " of " & iExportTotal
iCurrentExport += 1

' 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

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
sTempAssemblyFileName = ioPath.Combine(sTempFolder, Replace(occ.Name, ":", "_") & ".iam")

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 = 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
oCompOccPart.CreateGeometryProxy(oBimConnDef.Geometry.Item(j), oObj)
collGeo.Add(oObj)
Next

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 = BIMComponentOrientationTypeEnum.kModelOriginOrientationType' 103683 '103681 = ViewCube, 103683 = UCS, 103682 = Model Origin


' 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

' ' 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 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
0 Likes
Message 16 of 18

thomas.BaunachVVBHV
Participant
Participant

Hi Jhoel,

 

Again Thanx - yes, your changing did the trick...  works now as it should 😏

0 Likes
Message 17 of 18

urban.ostirZ44XW
Participant
Participant

Is it possible to use @JhoelForshav code for exporting RVT files?

 

Sub Main
	Dim oDlg As New FolderBrowserDialog
	oDlg.Description = "Select folder to save RFA-files"
	oDlg.ShowDialog
	If oDlg.SelectedPath = "" Then Exit Sub
	Dim oPath As String = oDlg.SelectedPath
	Dim oAsmDoc As AssemblyDocument = ThisDoc.Document
	If MsgBox("Do you want to continue?", vbOKCancel + vbExclamation, "Batch Create RFA") = vbCancel Then Exit Sub
	Dim oCompDef As AssemblyComponentDefinition = oAsmDoc.ComponentDefinition
	Dim oLeafOccs As ComponentOccurrencesEnumerator = oCompDef.Occurrences.AllLeafOccurrences
	Dim oTotal As Integer = oLeafOccs.Count
	Dim oProgressBar As Inventor.ProgressBar = ThisApplication.CreateProgressBar(False, oTotal, "Exporting to RFA", False)
	ThisApplication.UserInterfaceManager.DoEvents
	oAsmDoc.ComponentDefinition.RepresentationsManager.ActiveDesignViewRepresentation.HideAll
	Dim oBIMcomponent As BIMComponent = oCompDef.BIMComponent
	Dim i As Integer = 1
	Dim oOcc As ComponentOccurrence
	For Each oOcc In oLeafOccs
		oOcc.Visible = True
		Dim oOccName As String = oOcc.Name.Replace(":", "_")
		Dim FullFileName As String = oPath & "\" & oOccName & ".rfa"
		oProgressBar.Message = "Exporting " & FullFileName & " (" & i & "/" & oTotal & ")"
		oProgressBar.UpdateProgress
		ThisApplication.UserInterfaceManager.DoEvents
		oBIMcomponent.ExportBuildingComponent(FullFileName)
		oOcc.Visible = False
		i += 1
	Next
	oProgressBar.Close
	oAsmDoc.ComponentDefinition.RepresentationsManager.ActiveDesignViewRepresentation.ShowAll
End Sub
0 Likes
Message 18 of 18

lewis_sutherlandP6G4K
Explorer
Explorer

Hi Jhoel!

Thank you very much for sharing your script. Would you have any advice for how I would be able to specify a consistent UCS (Orientation) for the export of multiple assemblies sitting within a 'master' assembly file?

Any help would be greatly appreciated!

0 Likes