Tuesday, August 9, 2011

Copy Design and Revision Rolling with iLogic

You follow a strict item based filing system that results in one Inventor model file and one Inventor drawing file for each part number. This system works well and allows you to stay organized and control revisions without confusion or the need to ever move files around. However, you still find yourself copying these file pairs whenever you roll revision levels or when creating "same but different" designs. You'd like to use iLogic to copy, rename, and update links within the files.

Here is a a bit of sample code that uses the folder paths as the input and then parses these paths out into the part number and revision number properties. Once the files are copied to the new path and renamed according to the part number and revision level taken from the path, the file is opened and the internal file references are updated so that the new drawing is looking at the new model. Then a select group of iProperties are updated and the files are saved.

You can modify the code to match your own filing system, but I've provided it here as it works with the system I use most often.

First let's look at my typical folder set up to see how this code approaches the file folders and paths. In the first image below, each part number has its own folder, such as 12-2345-78. In this folder there are two sub-directories called Design Inputs and Design Outputs. The inputs folder is where data-sheets, e-mails, white-board captures, pictures, etc. would go. The outputs folder contains revision level folders where the Inventor files, a PDF version of the drawing file, an XLS file exported from the parts list, etc. reside.

So the path for the file shown would be:
D:\12-3456-78\Design Outputs\Rev 1 (where D:\ is the root of the engineering drive)

So with this folder structure in mind, let's have a look at the iLogic in action.

I create this rule as an external rule as shown, and then I run the rule from the iLogic browser. Note that the rule isn't run on the open file, but you do need to have at least one file open to access the rule in the browser (typically I just leave an new IPT open.)


 When the rule is run I am first greeted with an input box:

Rather than typing the path, I just copy the path from the address bar of the folder I want to copy:

And then I just paste it in and click OK.

Next, another input box asks for the new part number path. If the intent was to roll the revision I would just paste in the previous path again and then change the last number(s). In this example I'm copying item 12-3456-78 Rev 1 to a new part number: 22-1000-00 Rev 1:


Next I'm asked if the Description needs to change. If this was just a revision change, I'd click No, and skip the next input box. In this case I'll click Yes.

I enter the description for the new design and click OK:

Now the original files are copied over to the new folder (if the new folder doesn't exist, it gets created), and the file names, iProperties and internal links are all set to match the new files. When this is all done I get a confirmation message:

And then the destination folder is opened automatically for me:

If I look back at the original folder I'll notice that there was a PDF and an XLS file in that folder, but they were filtered out of the copy process, because they were not Inventor files.

So I'll go back to the new copies, and open the IDW file to ensure that it is looking at the new model file and not the original one. And sure enough I see that the View reference and the Parts List reference are both looking at the new assembly file. The title block has been updated as well, since it reads in the iProperties and they are being set by the rule also:

So now I'm ready to open the assembly and make design changes as needed, and this drawing will update as expected.

Here are a few things to know about how this code works:
  • Only Inventor files with Inventor extensions will be copied
  • Although the example I used involved an assembly and drawing file, this works fine with part and drawing pairs as well.
  • I've commented the code fairly well, so you should be able to dissect it if you have some basic familiarity with using iLogic and Inventor's API.
  • The iLogic will replace all of the existing references in a drawing with the new model file. That means that if a drawing of a bolt had one view of the bolt and another view of say, a battleship, both views would end up referencing the bolt in the copied files.
  • You can place any model and a drawing in a folder and then enter the path of that folder for each input path, and the iLogic will replace the references in that drawing with references to that model.
 The code is provided As Is and is not supported for troubleshooting or guaranteed to be bug free or to handle errors smoothly. You should probably consider this example code to be provided for you to build your own copy tool, rather than thinking of it as a finished tool that will fit your exact needs.

With that said, should you improve upon it or come up with variations that you think others would find useful, feel free to contact me and I'll post your version for others to find.

You can find the code in a text file here (mediafire link), or review the code below.

'-----------start of ilogic ---------------------
'this code is set up to use the user provided path to define
'part number, revision number, and file name for the copied file

'this code expects a path such as N:\12-3456-78\Design Outputs\Rev 1
'where 12-3456-78 is the part number and folder that all files for that part number reside in
'where Design Outputs is an intermediate folder
'where Rev 1 is the folder containing the files to be copied

'source directory
Dim strSDir As String

'get the source directory path (folder to copy file from) from the user
strSDir = InputBox("Enter path of files to copy", _
"iLogic Copy/Roll Revision", "",MessageBoxButtons.OKCancel) & "\"

'Cancel if input path is empty
If strSDir  = "" & "\" Then
End If

'destination directory
Dim strDDir As String

'get the destination directory path (folder to copy file to) from the user
strDDir = InputBox("Enter New Part Number Folder Path" & vbLf & _
"Or enter the same path again to update" & vbLf & _
"the linked file references and iProperties" & vbLf & _
"for the files at that path", "iLogic", "")

If strSDir = strDDir & "\" Then
oAlert = MessageBox.Show("The paths you entered are the same." & vbLf & _
            "This will update the linked file references and iproperties" & vbLf & _
            "for the files in this folder." & vbLf & _
            "Do you want to continue?", "iLogic",MessageBoxButtons.YesNo)
If oAlert = vbNo Then
On Error Resume Next
End If
End If

'Cancel if input path is empty
If strDDir = "" Then
End If

'if the destination directory does not exist, then create it
If(Not System.IO.Directory.Exists(strDDir )) Then
System.IO.Directory.CreateDirectory(strDDir )
End If

'defines backslash as the subdirectory separator
Dim strCharSep As String = System.IO.Path.DirectorySeparatorChar

'set array for each folder name found between backslashes in the source directory path
Dim oOrigPathItems() As Object = strSDir.Split(strCharSep)

'set array for each folder name found between backslashes in the destination directory path
Dim oNewPathItems() As Object = strDDir.Split(strCharSep)

'get the first level folder name to use as the original Part Number, expects a path such as
'N:\12-3456-78\Design Outputs\Rev 1
'returns: 12-3456-78
Dim strPN As String = oOrigPathItems(1)

'get the first level folder name to use as the new Part Number, expects a path such as
'N:\20-2000-20\Design Outputs\Rev 2
'returns: 20-2000-20
Dim strNewPN As String = oNewPathItems(1)

'get the second level folder name, expects a path such as
'N:\12-3456-78\Design Outputs\Rev 1
'return2: Design Outputs
'Dim strString As String = oOrigPathItems(2)

'get the thrird level folder name to use as the Revision Number, expects a path such as
'N:\12-3456-78\Design Outputs\Rev 2
'returns: Rev 2
Dim strNewRev As String = oNewPathItems(3)

'look at the source directory for the original file names
Dim strOrigFiles As String = Dir(strSDir)

Dim strNewFile As String 'new file name
Dim strExt As String 'File Extension
Dim strPNShort As String

'loop through the files in the source directory until all have been indexed
Do Until strOrigFiles = ""
            'set a message in Inventor's status bar
            ThisApplication.StatusBarText = "Please Wait"
            'On error resume Next

            'get the file extension for the current indexed file
            strExt = LCase(System.IO.Path.GetExtension(strOrigFiles))

                   'check to see if the file extension is not one of these 5 Inventor file extensions
                        If strExt <> ".ipt" _
                                    And strExt  <> ".iam" _
                                    And strExt  <> ".idw" _
                                    And strExt  <> ".dwg" _
                                    And strExt  <> ".ipn"  Then 
                   'do nothing
                   'set the new file name, using the user supplied destination directory,
                        'the Part Number, as found in the destination path,
                        'the Revision Number, as found in the destination path,
                        'and the file extension from the original file being indexed
                        strNewFile = strDDir & "\" & strNewPN & " " & strNewRev & strExt
                        'copy the file, using the source directory & the original currently indexed file,
                        'to the new file name              
                        FileCopy (strSDir & strOrigFiles, strNewFile)
                   'set a message in Inventor's status bar           
                        ThisApplication.StatusBarText = "Still Working"
                        End If
          'call Dir again (looking at the source directory still) without any arguments
            'this returns the next file in the same directory
            strOrigFiles = Dir()
          ' re-index the file extension for the next file
            strExt = LCase(System.IO.Path.GetExtension(strOrigFiles))

'- - - - now the code will look at the destination folder

'look at the destination directory for the new copied file names
Dim strCopiedFileName As String  = Dir(strDDir & "\")
msgQuestion1 = MessageBox.Show("Change Description?" & vbLf & _
            "If copying a design, select yes," & vbLf & _
            "If rolling a revision, select no.", _
            "Description - " & strPN & " " & strNewRev,MessageBoxButtons.YesNo)
          If msgQuestion1 = vbYes Then
          oDesc = InputBox("Enter Description.", _
            "Description - " & strNewPN & " " & strNewRev,"")
          oDesc = ""
            End If
Dim invDoc As Document               
'loop through the files in the destination directory until all have been indexed
Do Until strCopiedFileName = ""

            'get the file extension for the current indexed file
            strExt = System.IO.Path.GetExtension(strCopiedFileName)

          'check to see if the file has an Inventor file extension
            If strExt <> ".iam" _
                        And strExt <> ".ipt" _
                        And strExt <> ".idw" _
                        And strExt <> ".dwg" _
                        And strExt <> ".ipn"  Then
           'do nothing if the file does not have an inventor extension
          'set the indexed file path, using the user supplied destination directory,
        'the Part Number, as found in the destination path,
        'the Revision Number, as found in the destination path,
        'and the file extension from the original file being indexed
        strNewFile = strDDir & "\" & strNewPN & " " & strNewRev & strExt

            'open the indexed file, false opens the file without generating the graphics
            invDoc = ThisApplication.Documents.Open(strNewFile, False)
                   'check to see if the indexed file is an Inventor drawing
                        If (invDoc.DocumentType = kDrawingDocumentObject) Then
                   'if the file is an Inventor drawing set a reference to it
                        Dim DrgDoc As DrawingDocument
                        DrgDoc = invDoc
                        'crack the file and reset the internal references
                        'all references are reset to the same new reference
                        Dim oRefFile As FileDescriptor
                        For Each oRefFile In DrgDoc.file.ReferencedFileDescriptors
                                    'get the full file path to the original internal references
                                    Dim oOrigRefName As Object     
                             oOrigRefName = oRefFile.FullFileName

                                    'get the original referenced file externsions
                                    Dim strRefExt As String = System.IO.Path.GetExtension(oOrigRefName)

                             'set the new internal reference path and name
                                    'using the new file name and the original reference extension
                                    Dim strNewRefName As String = Mid(strNewFile, 1, Len(strNewFile)- 4) & strRefExt

                                    'if the new file name string is empty do nothing
                                    If (strDDir & "\" & strNewRefName) = "" Then 'do nothing          
                                    'otherwise replace the reference                                                  
                            Else oRefFile.ReplaceReference (strNewRefName)                                                          
                          End If
                  End If
          '--------this section sets the iproperties for the new files -------                  
            'note: see http://www.autodesk.com/us/community/mfg/Part_4.pdf for list of all property sets
            'define the iproperties summary property set
            Dim invSUMProperties As PropertySet
            invSUMProperties = invDoc.PropertySets.Item("Inventor Summary Information")
          'define the iproperties design tracking property set
            Dim invDTProperties As PropertySet                     
            invDTProperties = invDoc.PropertySets.Item("Design Tracking Properties")
          'set the revision number
            invSUMProperties.Item("Revision Number").Value = Mid(strNewRev,5)
          'set the author using the Application Options User Name
            invSUMProperties.Item("Author").Value = ThisApplication.GeneralOptions.UserName
            'set the part number
            invDTProperties.Item("Part Number").Value = strNewPN
                        'set the description if its a copied design, if it's a new revision keep the description
                        If oDesc = "" Then
                   invDTProperties.Item("Description").Value = invDTProperties.Item("Description").Value
                   invDTProperties.Item("Description").Value = oDesc
                        End If
          'set the Designer using the Application Options User Name
            invDTProperties.Item("Designer").Value = ThisApplication.GeneralOptions.UserName
            'set the creation time/date to the current date
            invDTProperties.Item("Creation Time").Value = Now()
          'save the file
            'close the file
            End If
          'reset the following items for the next file in the folder  
            invDoc = Nothing
            strCopiedFileName = Dir()
          'strExt = System.IO.Path.GetExtension(strCopiedFileName)

'set a message in the status bar
ThisApplication.StatusBarText = "Finished"
'tell the user the files were created
MessageBox.Show("New Files Created in " & strDDir, "iLogic")
'open the folder where the new folders are saved
Shell("explorer.exe " & strDDir,vbNormalFocus)

'-----------end of ilogic ---------------------