How to determine if a frame generated part is unique or not

How to determine if a frame generated part is unique or not

roy7BB24
Advocate Advocate
773 Views
8 Replies
Message 1 of 9

How to determine if a frame generated part is unique or not

roy7BB24
Advocate
Advocate

Hi All, 

I'm about to start writing a rule designed to determine if a frame generated part is unique and assign a part number to each unique frame member. I'm starting to use tube laser more and more, and I'm finding the standard method part number = section - length, isn't working. For example, if I have a rectangular frame with 4 mitered join's (see snip) and I specify a hole in one of the members, the goal is to find a way to identify that this is different to the member with the same length on the opposite side. This is obviously a simple case, but you get the idea. Of course, I could set the BOM to turn off the merging the BOM rows when part numbers match, but the goal here is to create something a little more elegant.

So, my current plan is to write a script that will record all the parameters of the in an excel spreadsheet, compare the columns and the either assign a new part number or duplicate the part number of an existing identical member. 

At this stage my question revolves around this; Due to the way frame generator works, there's a lot that's not captured in the parameters I can see. I could (and likely would) also use the physical properties of the model (mass, COG, surface area, whatever else turns out to be relevant. Is this method going to get the results I'm after or is there some way to compare solid bodies that would achieve better results? Or an entirely different method entirely. 

 

Any assistance would be much appreciated

 

Kind Regards

 

Roydon Mackay

0 Likes
774 Views
8 Replies
Replies (8)
Message 2 of 9

A.Acheson
Mentor
Mentor

You could probably check the feature counts, types of the solid body for each part number. And as you say the mass is also a good one. Potentially you could write some code detection to place custom iproperties with information of these features etc similar to the built in mitre/notch. But of course it might be just best to place an index number in the part number to identify it as custom part. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 3 of 9

roy7BB24
Advocate
Advocate

Hi Alan

I'm working on this once again, 

I've started with a basic approach, the idea is to run from the main assembly, and sequentially number all parts until it hits the frame, then run a sub routine to identify which members are unique and calculate quantities for all parts. At some point I need to work out how to tell the program what the final part number was used in the frame so that the program can carry on from there but not super worried about that now. 

I've identified the key parameters I'm going to work with for now are;

Section, Length, Material, Mass, Area, Volume, COGX, COGY & COGZ with most of these properties being drawn from the physical tab of the iproperties for each part. 

Just for right now, I'm running a test that tries to read the value and write it into a custom "test" variable in each part so I can check I'm getting the information to start, and it looks like I'm getting nothing, I'm also not entirely sure how to get these variables like this, its a little different to the other examples I've found, If you able to point me in the right direction it would be much appreciated

 

Kind Regards

 

Roydon Mackay

Sub Main
	'Reference to the Assembly Document
	Dim Doc As AssemblyDocument = ThisApplication.ActiveDocument

	'Reference to the BOM
	Dim BOM As BOM = Doc.ComponentDefinition.BOM

	BOM.PartsOnlyViewEnabled = True

'Enable Structured View
Dim BomView As BOMView = BOM.BOMViews.Item("Parts Only")

'Create the Assembly Counter Number
 'Dim Gen_Assembly_No As String = Doc.ComponentDefinition.PropertySets.Item(2).Item("PART NUMBER")
''Set the General Assembly Number as GEN-001 *To be changed later
'Gen_Assembly_No = ("001")

SetPartNumbering (BomView.BOMRows, 001)
End Sub

Private Sub SetPartNumbering (BOMRows As BOMRowsEnumerator, Assembly_No As String)
	'Iterate through the contents of the BOM Row's
	Dim Part_Counter As String = 001
	For i As Integer = 1 To BOMRows.Count
		'Get the Current Row
		Dim Row As BOMRow = BOMRows.Item(i)
		'Determine if the Bom Row is the Inventor Frame Assembly, if so start the subroutine to work through that sub assembly
		If Not Row.ChildRows Is Nothing Then
		 SetFrameGenPartNos(Row.ChildRows, 001)
		'If the item is a standard part, give it the next part number in the sequence 
        End If
	Next
End Sub

Private Sub SetFrameGenPartNos(BOMRows As BOMRowsEnumerator, Start_Number As String)
	'Iterate through all rows of the frame
	For i As Integer = 1 To BOMRows.Count
		'Get the Current Row
		Dim Row As BOMRow = BOMRows.Item(i)
		
		'Reference the primary ComponentDefinition of the Row
		Dim Compdef As ComponentDefinition = Row.ComponentDefinitions.Item(1)

		'Get the key component properties from each part
		
			'Dim Section As String = Compdef.Document.Item(2).Item("STOCK NUMBER")
			Dim Length As Single = Compdef.Document.PropertySets.Item(4).Item(G_L).Value
			'Dim Material As String = Compdef.Document.Item(7).Item("MATERIAL")
			'Dim Mass As Single = Compdef.Document.Item(7).Item("MASS")
			'Dim Area As Double = Compdef.Document.Item(7).Item("AREA")
			'Dim Volume As Double = Compdef.Document.Item(7).Item("VOLUME")
			'Dim COGX As Double = Compdef.Document.Item(7).Item("X")
			'Dim COGY As Double = Compdef.Document.Item(7) Item("Y")
			'Dim COGZ As Double = Compdef.Document.Item(7) Item("Z")
		
		'Confirm that the values are being read from each part, write the value to a custom propert 'test'
		Try
			Dim TEST As [Property] = Compdef.Document.PropertySets.Item(4).Item("TEST")
			TEST.Value = Length
		Catch
			Compdef.Document.PropertySets.Item(4).Add(Row.ItemQuantity, "TEST")
		End Try
	Next
End Sub
		

 

0 Likes
Message 4 of 9

A.Acheson
Mentor
Mentor

You may have the names of the iproperties incorrect. Here is a rule to get the iproperties from a document. it is referenced in the API help in VBA. Open a frame member and run the rule. Look in the logger and all the iproperties are displayed.

  Dim doc As Document = ThisApplication.ActiveDocument
  For Each ps As PropertySet In doc.PropertySets
   	Logger.Info( ps.Name + " / " + ps.InternalName)
    For Each p As [Property] In ps
      Logger.Info( "  " + p.Name + " /" + Str(p.PropId))
    Next
  Next

 

AAcheson_0-1675628534646.png

Here is a quick execution of the iproperties each document. 

Sub Main()

	'https://knowledge.autodesk.com/support/inventor/learn-explore/caas/screencast/Main/Details/1168a742-a54a-47e4-8e5c-c8fdde6e56de.html
	Dim oAsm As AssemblyDocument = ThisDoc.Document
	Dim oTransaction As Transaction = ThisApplication.TransactionManager.StartTransaction(oAsm, "FG stock to part number") 'Make this a single transaction
	For Each oDoc As Document In oAsm.AllReferencedDocuments 'Traverse all referenced documents
		If oDoc.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _	'Frame generator component
			AndAlso oDoc.DocumentType = DocumentTypeEnum.kPartDocumentObject _'Part
			AndAlso oDoc.IsModifiable _	'Modifiable (not reference skeleton)
			AndAlso oAsm.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc).Count > 0 'Exists in assembly (not derived base component)

'				'Get the key component properties from each part.
				Try
					Dim Length As String = oDoc.PropertySets.Item("Inventor User Defined Properties").Item("G_L").Value
					Dim Description As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Description").Value
					Dim StockNumber As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value
					Dim Material As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Material").Value
					Dim Mass As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Mass").Value
					Dim Area As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("SurfaceArea").Value
					Dim Volume As String = oDoc.PropertySets.Item("Design Tracking Properties").Item("Volume").Value
					Logger.Info("DisplayName: " & oDoc.DisplayName)
					Logger.Info("Description: " & Description)
					Logger.Info("StockNumber: " & StockNumber)
					Logger.Info("Length: " & Length)
					Logger.Info("Material: " & Material)
					Logger.Info("Mass: " & Mass)
					Logger.Info("SurfaceArea: " & Area)
					Logger.Info("Volume: " & Volume)
				Catch
				End Try
		
		End If
	Next
	oTransaction.End 'End the trasaction
End Sub

 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 5 of 9

roy7BB24
Advocate
Advocate

Hi, 

I'm currently working on this again, one of the issues I'm having right now is how to determine what each item on the BomRow is by properties, I.e how to tell if a row is a frame or reference skeleton etc. which need to be handled differently. I've gone through the propertysets and it looks like I need to go through the Interests of the component. 

I'm using the following code to try and find the interests but its only putting out a very small amount of information, what am I doing wrong here?

Dim doc As Document = ThisApplication.ActiveDocument
For Each interest As DocumentInterest In doc.DocumentInterests
    Logger.Info(interest.Name)
Next

Note: I have seen some other forum posts that use the values of the specific interests I'm looking for, but would like to understand how to find these interests for myself if I could

Screenshot 2023-05-02 214759.png

0 Likes
Message 6 of 9

A.Acheson
Mentor
Mentor

Hi @roy7BB24 this really comes down to detective work. Try and see if you can put the display name of the occurrence in the same line as interest and see if it comes back with a meaningfull pattern. The API help is limited on help topics around this. I know from the original sample the skelton is read only so if you check if the occurrence has frame generated interests and not Modifiable then you will have the skelton. If you have seen other methods link them here and I can help or indeed someone more familiar with them could help you out. 

If this solved a problem, please click (accept) as solution.‌‌‌‌
Or if this helped you, please, click (like)‌‌
Regards
Alan
0 Likes
Message 7 of 9

roy7BB24
Advocate
Advocate

Ah, I'm really not experienced enough with VB to use what you told me there to find the interests. See my code below, its going to grow into something that renumbers all the parts in an assembly, but for now it's just going through and checking I'm identifying each Bom Row correctly. When it hits the frame assembly it begins the Sub "FrameProcessor", 

which at this stage is just iterating through the BOM Rows of the frame assembly and trying to identify the Reference Skeleton, and the frame parts. At this stage I'm using the code you mentioned using the frame generator interest and the ismodifiable property however that doesn't seem to distinguish between the reference skeleton and the members, what would you reccomend here?

 

Class GlobalVariable
	Public RevNo As String = 0
	Public AssemblyCounter As Integer = 2
	Public PartCounter As Integer = 1
Sub Main
	'Reference to the assembly document
	Dim Doc As AssemblyDocument = ThisApplication.ActiveDocument
	
	'Reference to the BOM
	Dim BOM As BOM = Doc.ComponentDefinition.BOM
	
	'Enable Structured View
	'BOM.StructuredViewEnabled = True
	
	'Reference to the structured BomView
	Dim BomView As BOMView = BOM.BOMViews.Item(1)
	
	'Set Part Numbers
	'SetPartNumbers(BomView.BOMRows)
	
	  'For Each ps As PropertySet In Doc.PropertySets
   '	Logger.Info( ps.Name + " / " + ps.InternalName)
    'For Each p As [Property] In ps
      'Logger.Info( "  " + p.Name + " /" + Str(p.PropId))
    'Next
	'Next
	
	RevNo = (Doc.PropertySets.Item("Inventor Summary Information").Item("Revision Number").Value)
	
	Dim Part_Num As String = Doc.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value
	'Logger.Info(Part_Num)
	
	SetPartNumbers(BomView.BOMRows, Part_Num)
	
	Doc.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "A-001-" + RevNo
	'Logger.Info(Doc.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value)
	
End Sub

Private Sub SetPartNumbers(BOMRows As BOMRowsEnumerator, PartNo As String)
		'iterate through the contents of the BOM Rows
		PartCounter = 1
		Dim NextPartNo As String
		For i As Integer = 1 To BOMRows.Count
			'Get the Current Row
			Dim Row As BOMRow = BOMRows.Item(i)
			'Reference to the primary ComponentDefinition of the Row
			Dim CompDef As ComponentDefinition = Row.ComponentDefinitions.Item(1)
			'If the Bom Row Item is a Frame Assembly then rename it to be in the Format A-***-FRAME-**
			'And then begin a process to rename each frame generated part
			If CompDef.Document.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _
				AndAlso CompDef.Document.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject
				CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "A-" + Format(AssemblyCounter, "000") + "-FRAME-" + RevNo
				Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a frame assembly")
				FrameProcessor(Row.ChildRows,PartNo)
		ElseIf CompDef.Document.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject
			'Determine if the Row is a standard assembly, rename the part and then iterate the main sub over child rows
			CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "A-" + Format(AssemblyCounter, "000") + "-" + RevNo
			AssemblyCounter += 1
			Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value +" Is a standard assembly")
		Else
			'Determine if the Row is a standard part, rename the part using the Convention A-***-P-***-** where the last two characters are the revision number
			'NextPartNo = PartNo + "-P-" + Format(PartCounter, "000")
			'CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = (NextPartNo)
			'PartCounter += 1
			'Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value)
			Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value +" is a standard part")
		End If
			'Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value)
			'If CompDef.Document.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}")
				'Logger.Info("This is a Frame Generated Part")
			'Else 
				'Logger.Info("This is a Standard Part")
			'End If
		Next
End Sub

Private Sub FrameProcessor(BOMRows As BOMRowsEnumerator, AssemblyPNo As String)
	'Interate through the contents of the Frame
	For i As Integer = 1 To BOMRows.Count
		'Get the current row
		Dim Row As BOMRow = BOMRows.Item(i)
		
		'Reference to the primary component definition of the Row
		Dim Compdef As ComponentDefinition = Row.ComponentDefinitions.Item(1)
		'Check if it is the reference Skeleton
		If Compdef.Document.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _
				AndAlso Not Compdef.Document.IsModifiable 
				Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value +" Is a skeleton frame")
		'Check if its a standard part
		ElseIf Compdef.Document.DocumentInterests.HasInterest("{AC211AE0-A7A5-4589-916D-81C529DA6D17}") _
				AndAlso Compdef.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject
				Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a frame part")
		ElseIf Compdef.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject
			Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a standard part")
		End If
	Next
End Sub
End Class
	

 

0 Likes
Message 8 of 9

roy7BB24
Advocate
Advocate

Note: I considered assuming that if the volume/mass = 0 then it would be classified as a reference skeleton but would like something more robust if it exists

0 Likes
Message 9 of 9

roy7BB24
Advocate
Advocate

Hi Folks,

If anyone else has the misfortune to be dealing with a problem like this, the following lines will work to identify each component

			'Check to see if it is the Frame Assembly
			If CompDef.Document.DocumentInterests.HasInterest("FrameDoc")

 

		'Check if it is the reference Skeleton
		If Compdef.Document.DocumentInterests.HasInterest("SkeletonDoc")

 

		'Check if its a frame member
		ElseIf Compdef.Document.DocumentInterests.HasInterest("FrameMemberDoc")

Hopefully it provides some help to you