Friday, 15 July 2016

Item Number on Drawing Views (multiple Parts Lists)

                If you remember, a while back I have created an ilogic code to add item number on drawing views (original post). Some companies like to detail parts along with assembles on same drawing or even on same sheet.

                I was doing a drawing for a frame and because there were mostly standard shapes that this frame was build out of I decided to document the rest of the components on same sheet. This was not an issue for my code but on frame generator drawings I don’t use a Parts list but rather a Material List.

                The difference is that it doesn’t have an “ITEM” column and so the code would fail to work. You can manually add a Parts List on the drawing outside the sheet but the code will still not work because it looks at the first PartsList on the sheet and in this case it was my Material List.

                Don’t get confused, Parts List, Material Lists, Cut-To-Length lists are all the same, just customized to show different info.

Parts List style
                Material Lists contains, total length, stock number, Description, Material and individual items are merged to show total quantity rather than number of each item.

Cumulated lengths 
                This is setup to work with Tube and Pipe members as well. Remember that Frame Generator use G_L as length and Pipes use PL for length and if you check the column settings for Quantity you will see that if the member is pipe (PL parameter exists) then it will use it as quantity.

Works with TP pipes.

                Now that we got that out of the way and familiarized ourself with the different type of Parts Lists let’s discuss the change in code.
                The original code was looking at the first parts list
        'oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)

                and we need it to search for a specific one “Parts List” so the code became
        For i=1 To oPartsLists.Count
               If oPartsLists.Item(i).Title = "PARTS LIST" Then
                       oPartsList = oPartsLists.Item(i)
                       Exit For
               Else
                'do nothing
               End If
        Next
 
                Here is the full code again version 1.3 (download link here)
-------------------------------------------------------------------------------------------------------------
' Set a reference to the drawing document.
' This assumes a drawing document is active.
Dim oDrawDoc As DrawingDocument
oDrawDoc = ThisApplication.ActiveDocument
 
Dim oSheets As Sheets
oSheets = oDrawDoc.Sheets
Dim oSheet As Sheet'Inventor.Sheet
Dim oViews As DrawingViews
Dim oView As DrawingView
Dim oPartsLists As PartsLists
Dim oPartsList As PartsList
 
For Each oSheet In oSheets
    'declare the PartsLists 
    oPartsLists = oSheet.PartsLists
 
            'try and get the parts list form the table of this sheet
            Try
                'this doesn't work when you have a material list like on frame drawings
                'oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)
                'place a parts list on the drawing and search for it 
                'rather than using an id number
                
                For i=1 To oPartsLists.Count
                    If oPartsLists.Item(i).Title = "PARTS LIST" Then
                        'MessageBox.Show("found table", "ilogic")
                        oPartsList = oPartsLists.Item(i)
                        Exit For
                    Else
                        'do nothing
                    End If
                Next
                
            Catch 'on error try and search all sheets for first found parts list            
                'iterate trough each sheet
                Dim j As Long
                For j = 1 To oDrawDoc.Sheets.Count
                    If oDrawDoc.Sheets.Item(j).PartsLists.Count > 0 Then Exit For
                Next
                            
                'this doesn't work when you have other parts lists like a 
                '"material list" like on frame drawing
                'oPartList = oDrawDoc.Sheets.Item(i).PartsLists.Item(1)
                'place a parts list on the drawing and search for it 
                'rather than using an id number to locate the first
            
                For i=1 To oPartsLists.Count
                    If oPartsLists.Item(i).Title = "PARTS LIST" Then
                        'MessageBox.Show("found table", "ilogic")
                        oPartsList = oPartsLists.Item(i)
                        Exit For
                    Else
                        'do nothing
                    End If
                Next
                'MessageBox.Show("parts list found on: " & j, "Title")
            End Try
            
    oViews = oSheet.DrawingViews            
    
    For Each oView In oViews
    
        'Get the full filename Of the view model
        Dim oModelFileName As String
        oModelFileName = oView.ReferencedDocumentDescriptor.ReferencedDocument.FullFileName
        'MessageBox.Show("view model name" & oModelFileName, "Title")
                
            ' Iterate through the contents of the parts list.
            Dim j As Long
            For j = 1 To oPartsList.PartsListRows.Count
                ' Get the current row.
                Dim oRow As PartsListRow
                oRow = oPartsList.PartsListRows.Item(j)
                'get filename of model in row
                Dim oRowFileName As String
                Try ' try and get the full file name of the PL item
                    oRowFileName = oRow.ReferencedFiles.Item(1).FullFileName
                Catch 'on error go to next item
'                    Dim oCellValue As String
'                    oCellValue = oRow.Item("Item").Value
'                    MessageBox.Show("Error Processing item: " & oCellValue, "Title")
                    Continue For
                End Try
                'compare the filenames
                'Performs a text comparison, based on a case-insensitive text sort order
                'If strings equal returns 0
                If StrComp(oModelFileName, oRowFileName, CompareMethod.Text)=0 Then 
                    'Get the value of Item from the Parts List
                    'Row name needs to be case sensitive or use 1 for first 2 for second etc.
                    oCell  = oPartsList.PartsListRows.Item(j).Item("Item") 
'Row name needs to be case sensitive or use 1 for first 2 for second etc.
                    'get the value of text in cell
                    Dim oItemValue As String
                    oItemValue = oCell.Value
                    
                    'Show the view label
                    oView.ShowLabel = True
                    'format the text first line
                    oStringItem = "<StyleOverride Underline='True' FontSize='0.35'> ITEM " & oItemValue & " </StyleOverride>"
                    'format the text second line
                    oStringScale = "<Br/><StyleOverride FontSize='0.3'>(Scale <DrawingViewScale/>)</StyleOverride>"
                    
                    'add to the view label
                    oView.Label.FormattedText =  oStringItem & oStringScale
                End If  
            Next
      Next
Next

------------------------------------------------------------------------------------------------------------
EDIT: 11/08/16
if you would rather be prompted to select views rather than processing all of them , here is the code.
------------------------------------------------------------------------------------------------------------

' Set a reference to the drawing document.
' This assumes a drawing document is active.
Dim oDrawDoc As DrawingDocument
oDrawDoc = ThisApplication.ActiveDocument
 
Dim oSheets As Sheets
oSheets = oDrawDoc.Sheets
Dim oSheet As Sheet'Inventor.Sheet
Dim oViews As DrawingViews
Dim oView As DrawingView
Dim oPartsLists As PartsLists
Dim oPartsList As PartsList
 
For Each oSheet In oSheets
    'declare the PartsLists 
    oPartsLists = oSheet.PartsLists
 
            'try and get the parts list form the table of this sheet
            Try
                'this doesn't work when you have a material list like on frame drawings
                'oPartsList = oDrawDoc.ActiveSheet.PartsLists.Item(1)
                'place a parts list on the drawing and search for it 
                'rather than using an id number
                
                For i=1 To oPartsLists.Count
                    If oPartsLists.Item(i).Title = "PARTS LIST" Then
                        'MessageBox.Show("found table", "ilogic")
                        oPartsList = oPartsLists.Item(i)
                        Exit For
                    Else
                        'do nothing
                    End If
                Next
                
            Catch 'on error try and search all sheets for first found parts list            
                'iterate trough each sheet
                Dim j As Long
                For j = 1 To oDrawDoc.Sheets.Count
                    If oDrawDoc.Sheets.Item(j).PartsLists.Count > 0 Then Exit For
                Next
                            
                'this doesn't work when you have other parts lists like a 
                '"material list" like on frame drawing
                'oPartList = oDrawDoc.Sheets.Item(i).PartsLists.Item(1)
                'place a parts list on the drawing and search for it 
                'rather than using an id number to locate the first
            
                For i=1 To oPartsLists.Count
                    If oPartsLists.Item(i).Title = "PARTS LIST" Then
                        'MessageBox.Show("found table", "ilogic")
                        oPartsList = oPartsLists.Item(i)
                        Exit For
                    Else
                        'do nothing
                    End If
                Next
                'MessageBox.Show("parts list found on: " & j, "Title")
            End Try
            
    oViews = oSheet.DrawingViews            

        'get view from user
        While True
            oView = ThisApplication.CommandManager.Pick( _
            SelectionFilterEnum.kDrawingViewFilter, "Select a View") 
        
            'Get the full filename Of the view model
            Dim oModelFileName As String
            oModelFileName = oView.ReferencedDocumentDescriptor.ReferencedDocument.FullFileName
            'MessageBox.Show("view model name" & oModelFileName, "Title")
                
            ' Iterate through the contents of the parts list.
            Dim j As Long
            For j = 1 To oPartsList.PartsListRows.Count
                ' Get the current row.
                Dim oRow As PartsListRow
                oRow = oPartsList.PartsListRows.Item(j)
                'get filename of model in row
                Dim oRowFileName As String
                Try ' try and get the full file name of the PL item
                    oRowFileName = oRow.ReferencedFiles.Item(1).FullFileName
                Catch 'on error go to next item
'                    Dim oCellValue As String
'                    oCellValue = oRow.Item("Item").Value
'                    MessageBox.Show("Error Processing item: " & oCellValue, "Title")
                    Continue For
                End Try
                'compare the filenames
                'Performs a text comparison, based on a case-insensitive text sort order
                'If strings equal returns 0
                If StrComp(oModelFileName, oRowFileName, CompareMethod.Text)=0 Then 
                    'Get the value of Item from the Parts List
                    'Row name needs to be case sensitive or use 1 for first 2 for second etc.
                    oCell  = oPartsList.PartsListRows.Item(j).Item("Item") 
                'Row name needs to be case sensitive or use 1 for first 2 for second etc.
                    'get the value of text in cell
                    Dim oItemValue As String
                    oItemValue = oCell.Value
                    
                    'Show the view label
                    oView.ShowLabel = True
                    'format the text first line
                    oStringItem = "<StyleOverride Underline='True' FontSize='0.35'> ITEM " & oItemValue & " </StyleOverride>"
                    'format the text second line
                    oStringScale = "<Br/><StyleOverride FontSize='0.3'>(Scale <DrawingViewScale/>)</StyleOverride>"
                    
                    'add to the view label
                    oView.Label.FormattedText =  oStringItem & oStringScale
                End If  
            Next
      End While
Next
------------------------------------------------------------------------------------------------------------
Later,
ADS
               

                

Monday, 4 July 2016

Fitting Engagement Distance


This has been in my drafts way to long. I only allowed myself to publish new posts if there is one ready to go in my drafts. Even though I am not back to normal I feel this might help me move towards normality even if I might never get there again.


Can fittings have both male/female connections and different engagement distance?



My friend asking this was referring to elements like bushings, and reducers as in the image bellow where the right side connection can fit 2 sizes, one inside (female) and one outside (male). These will need different engagement distances as well.

3 connections on same fitting.
Library or stand alone?


There is no gender on the fittings; they are all connected by points and axes but how you author it depends on what you intend to do with the file. Is this for an ipart to be published to Content Center, or is it a standalone library file?

More than likely this will be used in content center but if this is a standalone library then you need to author this in a weird way with 3 connections instead of 2. When you place the fitting press Spacebar until it shows the correct position.

While this is possible I think most of you will need this in Content Center. For that you will create two identical shape members with different connections.

Even though these members will have identical part number, stock number and whatever fields you use to identify this, the filename needs to be unique. This is one rare occasion when I allow filename to be different than the part number.

How do we create a dynamic engagement distance? You create an offset work plane and you control the offset value from the ipart table.
 
offset plane
 
ipart table

In the author fitting window choose Engagement, To Plane, Point and choose our plane.

 
Authoring, To Plane / Point
Later,


ADS.


photo credit: parts (license)

Monday, 27 June 2016

Updates

Would like to thank you all for the kind messages and warm wishes. It has been a difficult time and I am still struggling to get back normality, trying to get back into routine.

About 12 weeks ago my father has passed away and I have been blown to pieces to a point where I didn’t felt like doing anything. I didn’t want to go back to work and I had to push myself really hard to do the usual, chores and routine.

The only thing that made sense and that kept me going was my family, playing with my son and spending as much time with them as I could.

Here is my son Aiden, 18 months old now.

Cheeky monkey
While being a contractor helps you keep active and prevents you from getting dull or complacent, it also means you need to carry on no matter what; no work, no pay. I had to keep going and provide for my family but it was really difficult at times.

I need to thank my friends, family and colleagues for support and understanding. This wasn’t totally unexpected but he really was a special person who has positively influenced everyone around him.

I haven’t been totally absent and I have been in contact with Autodesk on various subjects, one being Tube and Pipe. We have a plan forward and while I’ve gathered another 60 ideas on T&P it’s best we split the overhaul post and create individual requests for each one of them.

The original plan was to keep it all as a single entry and make the developers get the full picture but the negative comments are turning users away from T&P. What we need to understand is that some of my requests are referring to Inventor in general, others are my own imagination, and some of them are not to be found in any other pipe design software. While I wish my car had screen-in-screen mirrors and self adjusting dash lights it doesn’t make it a bad car and it’s certainly no indication on the performance of the vehicle.

Long time ago (about 13 years to be more exact) I have asked and older/experienced colleague what is the best CAD software and while it all depends on discipline / product / design you are doing his answer was far simpler:

“The best CAD software is THE ONE YOU KNOW”.

My reply is a simple comparison on my work place. The design office in am in Veolia is one of the few that uses Autodesk Inventor; default recommended package throughout the group is ProE/Creo but there are also Aveva PDMS users as well. This makes us one of the most productive offices as well because Inventor gives us the speed and flexibility to work in ways other cannot. For some of our projects we only get 5-10 hours design time and that includes, P&ID, plant layout, renderings, along with saving and sending in various formats, setting up the projects, drawing register, etc.

On the other extreme I am currently working on a project with equipment from ProE, vessels from SolidEdge, skids from SolidWorks, building components from Revit and Tekla via .ifc conversions, sketches from Autocad and I am adding Tube and Pipe with Autodesk Inventor. I then export it to A360 Glue (sort of navisworks in the cloud) via Navisworks Mange. Forgot to mention that the building has ReCap scans and we have imported the point clouds in Inventor for validating pipe routing and clearing clashes.

Other departments will need more time to setup the project and the libraries while we’ve finished the entire job.

Yes Inventor has room for improvement but the more users there are the better the software will get so don’t just discard it based on a list form a lunatic that has nothing better to do with his time and he posts all sort of crazy requests on Idea Station.

So what now? Will try and ease in, find my balance, one step at a time and see if I can get up to running speed again.


ADS. 


Thursday, 10 March 2016

Precise Move Components

Is there a way to select components in an assembly and move them all an exact relative distance?

Sometimes we just need to move a group of components in a certain direction all at once and if they are constrained together then it is just a matter of editing the constraint value but what if they are not constrained one to another or what if the parts are not constrained at all.

Some of foreign models we receive are translated as assemblies with parts but as you know those are not constrained but rather placed together and they are free to move around.

If the whole imported assembly needs moving that’s easy, right? Just constrain it and then edit the dimension value but what if you need to reposition some of the parts inside the assembly?

My blogs seem to be related to one another and while this is not entirely intentional I think you will remember them better, just like in school when we were told the same thing over again till we got it.

The way to move several components (parts/assemblies) at once is to demote them to a temporary assembly, move/constrain them, and then promote them again. Because constraints work with faces, axes, planes, they will follow the members (parts/assemblies) no matter how you move them in the tree structure, in other words Promote/Demote will not mess up the constraints.

For example, say you have 4 chairs constrained to the floor and you need to move them together an exact, relative distance. When you demote the chairs the assembly containing them will have 4 constraints to the floor and after you move the assembly around and you promote the chairs you will see that each is constrained to the floor.

If the components need to move along the origin axis then you are better/faster to edit the value in the iproperties / Occurrence tab / “Current Offset from Parent Assembly Origin”.

Select your components you choose to move and press TAB key or use right click Component / Demote command. Don’t worry about giving a proper name or save location, we will never save this assembly on disk. It will stay in memory just till we finish with moving.

Demote components

TIP: In browser you can use SHIFT, CTRL select but in the graphical window you can use window selection.

Click OK in the Create In-Place Component window and then right click the newly created assembly and choose iproperties.

Precise move.

Head over to Occurrences tab and change the value in the X,Y,Z direction as you need.

You can use the origin indicator to help with choosing dimension. Remember that a negative value will move it against the axis direction (check the arrow indication) while a positive value will move in the direction of the axis.

Find the assembly in the browser and promote all of it’s components back again. You will notice that they have kept the new position.

Promote components

Delete the temporary assembly and choose No in the save dialog window.

Delete temp assembly.

It might not be that often that you will use it but it’s good info to have when dealing with large imports.

Short animation.

Later,
ADS


photo credit: mic (license)

Monday, 7 March 2016

Removing phantom fittings

                Although similar with last post I need to share some tips on how to populate a corrupted route again. Last post we discussed how to delete fittings and today we are using the info there to remove fittings and segments that don’t update. 


                This is a scenario that I see a lot and it refers to broken links and updates on the fittings. You modify a route and when you try and update the run you realize that some / all fittings don’t update position and sometimes Inventor creates a complete new set of pipes and fittings ignoring the existing ones.

                I don’t have a case at hand but I will share the one on Autodesk Forum I have been answering and which can be seen here.
               




                As you can see from the images, Inventor decided to keep some segments in place when the route has been changed.

                A different case would be when you need to remove the populated fittings and segments from a route like in this post here.
               
                Just like in my previous post you need to move the fittings and segments outside T&P assembly (promote) and then demote them to a new assembly which can then be deleted.

                The problem is, once you move those fittings you can’t populate the route again. We are technically hiding the elements outside TP and then we delete them so the route has no clue that the parts have been deleted.

                If you do need to populate it again then I have a trick and this is the reason we are here today.

                The route can’t be populated again but you can copy/paste it and then make it adaptive and this will replicate your exact route. Because you are doing this at the route level (instead of run level) you will get the default fittings and not any manually placed ones (valves, reducers, etc.) but nonetheless it is far better than sketching the route again.

                Inventor will NOT place the route in the original location and you will see it at a distance adjacent to the corrupted one.  As a rule any new files will be created at assembly origin and that means that any route will be located at the run origin but without constraints. You can always check the position of the original one by checking the iproperties/occurrences tab.

                You have two options to move the route to a new location:

1                1 - You have not used the Make Adaptive command yet. Once you paste the route you can then right click on it and in the iproperties / Occurrences tab you can enter 0 in the “Current Offset from Parent Assembly Origin” and then click apply. Then you can use the Make Adaptive command.

Position route at origin.
Make Adaptive menu.

                2 - If you have use the Make Adaptive and even used the Populate Route command you can repeat the steps before but in the Occurrences tab take of Adaptive first and then put 0 in the offset value fields. As soon as you click apply, the Adaptive box should be ticked automatically for you if not make sure to put it back. You can't just change the position of an adaptive route or you will get this error:
"
                "Properties: problems encountered while executing this command
                Invalid input for Request"


Take off Adaptivity first.

Limitations:

-          You still need to connect the route to your equipment around.
-          Sometimes, if the location of fittings and segments don’t update you need to edit the route and simply click on “Finish Route” to force an update. Update button or rebuild all will not help you.

Force update the fittings and segments.
Small animation of the process.

This trick is part of the “How to constrain my TP assembly and its components” blog which will come at a later time. Way too many to handle at once.

Latter,
ADS.


photo credit: fittings (license)