If, for instance I know ahead of time what the rough structure of my assembly is going to be (based on a file structure from a CD I was given) how easy is it to recreate this structure using iLogic?
My file structure looks a little like this:
<dir name="e:\"> <file parentassembly="THE-TOP-LEVEL-ASSEMBLY" friendlyname="TOP-LEVEL-ASSEMBLY" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="PART-NAME" /> <dir name="1ST-LEVEL-SUB-ASSEMBLY"> <file parentassembly="TOP-LEVEL-ASSEMBLY" friendlyname="1ST-LEVEL-SUB-ASSEMBLY" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="2ND-LEVEL-SUB-ASSEMBLY-003" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="2ND-LEVEL-SUB-ASSEMBLY-004" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="PART-NAME" /> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="PART-NAME" /> <dir name="2ND-LEVEL-SUB-ASSEMBLY-000"> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="2ND-LEVEL-SUB-ASSEMBLY-000" /> </dir> <dir name="2ND-LEVEL-SUB-ASSEMBLY-001"> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="2ND-LEVEL-SUB-ASSEMBLY-001" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-001" friendlyname="PART-NAME" /> </dir> <dir name="2ND-LEVEL-SUB-ASSEMBLY-002"> <file parentassembly="1ST-LEVEL-SUB-ASSEMBLY" friendlyname="2ND-LEVEL-SUB-ASSEMBLY-002" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> <file parentassembly="2ND-LEVEL-SUB-ASSEMBLY-002" friendlyname="PART-NAME" /> </dir>
Incidentally, the above code was created from a small console app I wrote:
Imports System.Collections.Generic Imports System.IO Imports System.Linq Imports System.Text Imports System.Text.RegularExpressions Imports System.Xml.Linq Module Module1 Public Sub Main() Console.WriteLine("Enter Path to Parse...") Dim rootPath As String = Console.ReadLine() Dim dir = New DirectoryInfo(rootPath) Dim doc = New XDocument(GetDirectoryXml(dir)) doc.Save("C:\temp\VBtest.xml") Console.WriteLine(doc.ToString()) Console.Read() End Sub Public Function GetDirectoryXml(ByVal dir As DirectoryInfo) As Object Dim info = New XElement("dir", New XAttribute("name", dir.Name)) If Not dir.Name.Contains("Superseded") Then For Each file As FileInfo In dir.GetFiles() 'info.Add(New XElement("file", New XAttribute("name", file.Name), New XAttribute("friendlyname", GetFriendlyName(file.Name)))) If Not file.Name.Contains("IL") And Not file.Name.Contains("DL") And Not file.Name.Contains("SP") Then 'if the directory name is the same as the assembly name then the parentassembly is the folder above! If GetFriendlyDirName(dir.Name) = GetFriendlyName(file.Name) Then If getsheetnum(file.Name) <= 1 Then info.Add(New XElement("file", New XAttribute("parentassembly", GetFriendlyDirName(dir.Parent.Name)), New XAttribute("friendlyname", GetFriendlyName(file.Name)))) End If Else If getsheetnum(file.Name) <= 1 Then info.Add(New XElement("file", New XAttribute("parentassembly", GetFriendlyDirName(dir.Name)), New XAttribute("friendlyname", GetFriendlyName(file.Name)))) End If End If End If Next For Each subDir As DirectoryInfo In dir.GetDirectories() If Not subDir.Name.Contains("Superseded") Then info.Add(GetDirectoryXml(subDir)) End If Next End If Return info End Function Public Function GetFriendlyName(p As String) As Object Dim f As String = String.Empty Dim r As New Regex("\w{2}-\d{5,}|\w{2}-\w\d{5,}") f = r.Match(p).Captures(0).ToString() + "-000" Console.WriteLine(f) Return f End Function Public Function GetFriendlyDirName(p1 As String) As Object If Not p1.Contains(":") Then Dim f As String = String.Empty Dim r As New Regex("\d{3,}|\w\d{3,}") f = "AS-" + r.Match(p1).Captures(0).ToString() + "-000" Return f Else Return p1 End If End Function Private Function getsheetnum(p1 As String) As Integer Dim f As String = String.Empty Dim pattern As String = "(.*)(sht-)(\d{3})(.*)" Dim matches As MatchCollection = Regex.Matches(p1, pattern) For Each m As Match In matches Dim g As Group = m.Groups(3) f = CInt(g.Value) Next Return CInt(f) End Function End Module
I was thinking that since the above works for folders/subfolders (because of the recursive nature) that it should work in Inventor iLogic (with some tweaks) for creating the sub-assemblies/parts etc.
Can anyone offer any pointers?
Thanks,
Alex.
Ilogic could be used to create assembly/subassemblies/components via direct calls to Inventor API objects.
See help on ComponentOccurrences collection methods Add(), AddByComponentDefinition(), AddWithOptions(), etc. Overview article on Building an Assembly and several code samples could be useful as well. Please note that all methods use input Matrix object that defines the location and orientation to position the occurrence.
cheers
Hi again Vladimir,
Apologies for my delayed reply.
Here is how I have been able to run my Visual Studio created .dll file from Inventor iLogic:
Basically, you need to make sure that the .dll file compiles to the c:\Program Files\Autodesk\Inventor 2014\Bin\iLogicAdd\ path
Then, using this code in an external iLogic rule:
AddReference "CreateAssemblyFromExcelVB.dll" Imports CreateAssemblyFromExcelVB Sub Main() Dim XTVB As New CreateAssemblyFromExcelVB.ExternalVBClass Dim FilesArray As New ArrayList Dim PartsList As List(Of CreateAssemblyFromExcelVB.SubObjectCls) PartsList = New List(Of CreateAssemblyFromExcelVB.SubObjectCls) 'pass the local variables to our external .dll XTVB.InventorApplication = ThisApplication Dim filetab As String = InputBox("Which project?", "Select Sheet Name", "SHEETNAME") FilesArray = GoExcel.CellValues("C:\VAULT WORKING FOLDER\Designs\Project Tracker.xlsx", filetab, "A3", "A4") ' opens and sets excel to the correct sheet! For MyRow As Integer = 3 To 5000 ' max limit = 5000 rows but could be much higher Dim SO As CreateAssemblyFromExcelVB.SubObjectCls If GoExcel.CellValue("A" & MyRow) = "" Then Exit For 'exits when the value is empty! Dim tmpstr As String = GoExcel.CellValue("I" & MyRow) 'parent row If Not tmpstr.StartsWith("AS-") Then Continue For End If 'capture iproperties from the available Excel Data. SO = New CreateAssemblyFromExcelVB.SubObjectCls(GoExcel.CellValue("B" & MyRow), GoExcel.CellValue("K" & MyRow), GoExcel.CellValue("L" & MyRow), GoExcel.CellValue("M" & MyRow), GoExcel.CellValue("I" & MyRow)) PartsList.Add(SO) Next XTVB.PartsList = PartsList GoExcel.Close Dim tr As transaction tr = ThisApplication.TransactionManager.StartTransaction(ThisApplication.ActiveDocument, "Create Standard Parts From Excel") Call XTVB.BeginCreateAssemblyStructure tr.End() InventorVb.DocumentUpdate() End Sub
This then calls the Visual Basic code that allows me to create an assembly based on the folder structure from the post above.
Hi Alex,
It's not clear to me if you still need help with something or you're all set?
Cheers,
Hi Adam,
I figured out everything I needed to know - once I was able to debug the code I was writing (in Visual Studio) all the problems melted away.
I will say this though: If you guys can figure out how to get debugging working in iLogic it'll be a massive bonus to everyone that uses it.
Thanks,
Alex.
Hi Alex,
To be honest I don't see that coming.
1) If you want to do some simple configuration then iLogic can be the right tool. Even if it requires the underlying Inventor API, you can figure things out and test in VBA first (or Visual Studio) which offers: debugging, intellisense, object model access, etc
2) If you need to create a serious project create an AddIn: debugging, intellisense, .NET forms/controls, etc
iLogic debugging only goes this far:
http://adndevblog.typepad.com/manufacturing/2014/08/debug-ilogic.html
Cheers,