Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Assistance Classifying Frame generated Members

roy7BB24
Advocate

Assistance Classifying Frame generated Members

roy7BB24
Advocate
Advocate

Hi all, I'm working on a way to determine if frame generated members are unique or duplicates of another member in a frame, and then assign them the existing part number or a new one as required. The part numbering is being done to match the rest of my general assembly, there's some loose rules in the code already, but I'm going to refine this as I go. Note I use a lot of tube laser and other processing so using the standard 50 X 50 RHS - 500 doesn't work as I often have two parts the same length with different features and need to be able to assign both different part numbers easily. 

In any case I've got a script currently that's pulling a bunch of information from each frame member, for now I'm just logging the info. I'm obtaining the following properties: Material, Stock No, Length, Mass, Volume, Surface Area, Ixx, Iyy, Izz. Currently I'm just logging the data, will sort once I've confirmed I'm getting the right outputs.

Obviously, plan is to sort by the easy things first (Material, Stock No, Length, Mass, Volume, Surface Area) and then if these all matches do a follow check of the centers of gravity. If there's two pieces of RHS with holes in slightly different locations, mass, surface area and volume will all match. This is fine I've sorted this, however if I have two pieces of RHS that are mirror images (see attached image or attached inventor file), the centers of gravity are coming back as identical.

I've had a look through the API help, and also this post which is somewhat similar (Solved: Accessing Inertial Properties using iLogic - Autodesk Community - Inventor), if anyone is able to offer any assistance it would be much appreciated. 

All rules are in the "Classifying assistance folder - TEST FRAME"

The relevant part of the rule is here:

Private Sub FrameProcessor(BOMRows As BOMRowsEnumerator, AssemblyPNo As String)
	'Interate through the contents of the Frame
	Dim frame As New Frame_Data
	Dim prelim As String
	Dim postlim As Single
	Dim MassProps As MassProperties
	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("SkeletonDoc")
			Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = (AssemblyPNo + "-SKELETON FRAME")
			Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a skeleton frame")

			'Check if its a frame member
		ElseIf Compdef.Document.DocumentInterests.HasInterest("FrameMemberDoc")
				Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a frame part")
				
				frame.Material = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Material").Value
				frame.Stock = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value
				frame.Length = Compdef.Document.PropertySets.Item(4).Item("G_L").Value
				prelim = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Mass").Value
				If Single.TryParse(prelim, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, postlim)
					frame.Mass = postlim
					Else 
					Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " - the mass for this part has not been entered correctly")
					End If
				prelim = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Volume").Value
				If Single.TryParse(prelim, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, postlim)
					frame.Volume = postlim
					Else 
					Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " - the mass for this part has not been entered correctly")
					End If
				prelim = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("SurfaceArea").Value
				If Single.TryParse(prelim, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, postlim)
					frame.Area = postlim
					Else 
					Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " - the mass for this part has not been entered correctly")
					End If				
				Logger.Info(" Material: " + frame.Material)
				Logger.Info("Stock No: " + frame.Stock)
				Logger.Info("Length: " + frame.Length)
				Logger.Info(String.Format("Mass: {0}", frame.Mass))
				Logger.Info(String.Format("Volume: {0}", frame.Volume))
				Logger.Info(String.Format("Surface Area: {0}", frame.Area))	
				MassProps = Compdef.Document.ComponentDefinition.MassProperties
				Dim adPrincipleMoments(0 To 2) As Double
				Call MassProps.PrincipalMomentsOfInertia(adPrincipleMoments(0),adPrincipleMoments(1),adPrincipleMoments(2))
				Logger.Info(String.Format("Ixx: {0}", adPrincipleMoments(0)))
				Logger.Info(String.Format("Iyy: {0}", adPrincipleMoments(1)))
				Logger.Info(String.Format("Izz: {0}", adPrincipleMoments(2)))
		'Check if its a standard 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

See Full code below: 

Class GlobalVariable
	Public RevNo As String = 0
	Public AssemblyCounter As Integer = 2
	Public PartCounter As Integer = 1
	Public GenPartCounter As Integer = 1
End Class
	
Public Class Frame_Data
	Public Property Material As String
	Public Property Stock As String
	Public Property Length As String
	Public Property Mass As Single
	Public Property Volume As String
	Public Property Area As String
	Public Property Ixx As Double
	Public Property Ixy As Double
	Public Property Iyy As Double
	Public Property Ixz As Double
	Public Property Iyz As Double
	Public Property Izz As Double
End Class	
	
Sub Main
	'Reference to the assembly document
	Logger.Info("Start Numbering Macro")
	Dim Doc As AssemblyDocument = ThisApplication.ActiveDocument
	
	Doc.Rebuild()
	'Rebuild the Document
	Dim CmdMan As ControlDefinition
	CmdMan = ThisApplication.CommandManager.ControlDefinitions.Item("AppUpdateMassPropertiesCmd")
    
    CmdMan.Execute
        CmdMan.Execute2 (True)
	'Update All Mass Properties
	'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)
	
	ResetItemCheck(BomView.BOMRows)
	
	Doc.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "A-001" 
	'Logger.Info(Doc.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value)
	Logger.Info("Initializing Complete, Begin Proccessing Assembly BOM")
	SetPartNumbers(BomView.BOMRows, Part_Num)
	
End Sub

Private Sub SetPartNumbers(BOMRows As BOMRowsEnumerator, PartNo As String)
		'iterate through the contents of the BOM Rows
		Logger.Info("Begin Setting Part Number of " + PartNo)
		Dim SketchCounter = 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("FrameDoc") _
				AndAlso CompDef.Document.DocumentType = DocumentTypeEnum.kAssemblyDocumentObject _
				AndAlso CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 0
				CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "A-" + Format(AssemblyCounter, "000") + "-FRAME-"
				CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 1
				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 _
			AndAlso CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 0
			'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") 
			CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 1
			AssemblyCounter += 1
			Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a standard assembly")
		ElseIf CompDef.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject _
			AndAlso CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 1
			CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "GEN-P-" + Format(GenPartCounter, "000")
			GenPartCounter += 1
			CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 2
			Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a general part")
		ElseIf CompDef.Document.DocumentType = DocumentTypeEnum.kPartDocumentObject _
			AndAlso CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Volume").Value = 0 _
			AndAlso CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 0
			CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = PartNo + "-LAYOUT-" + Format(SketchCounter, "00")
			CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 1
			SketchCounter += 1
			Logger.Info(CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a Layout Sketch")
		ElseIf CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 0
			'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
			CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = "P-" + Format(PartCounter, "000")
			CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 1
			PartCounter += 1
			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
		For i As Integer = 1 To BOMRows.Count
			Dim Row As BOMRow = BOMRows.Item(i)
			Dim CompDef As ComponentDefinition = Row.ComponentDefinitions.Item(1)
		If Not Row.ChildRows Is Nothing _
		And Not CompDef.Document.DocumentInterests.HasInterest("FrameDoc")
			SetPartNumbers(Row.ChildRows, CompDef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value)
		End If
		Next
		Logger.Info("Part Numbering of " + PartNo + " is complete")
End Sub

Private Sub FrameProcessor(BOMRows As BOMRowsEnumerator, AssemblyPNo As String)
	'Interate through the contents of the Frame
	Dim frame As New Frame_Data
	Dim prelim As String
	Dim postlim As Single
	Dim MassProps As MassProperties
	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("SkeletonDoc")
			Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = (AssemblyPNo + "-SKELETON FRAME")
			Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a skeleton frame")

			'Check if its a frame member
		ElseIf Compdef.Document.DocumentInterests.HasInterest("FrameMemberDoc")
				Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " Is a frame part")
				
				frame.Material = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Material").Value
				frame.Stock = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value
				frame.Length = Compdef.Document.PropertySets.Item(4).Item("G_L").Value
				prelim = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Mass").Value
				If Single.TryParse(prelim, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, postlim)
					frame.Mass = postlim
					Else 
					Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " - the mass for this part has not been entered correctly")
					End If
				prelim = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Volume").Value
				If Single.TryParse(prelim, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, postlim)
					frame.Volume = postlim
					Else 
					Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " - the mass for this part has not been entered correctly")
					End If
				prelim = Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("SurfaceArea").Value
				If Single.TryParse(prelim, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, postlim)
					frame.Area = postlim
					Else 
					Logger.Info(Compdef.Document.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value + " - the mass for this part has not been entered correctly")
					End If				
				Logger.Info(" Material: " + frame.Material)
				Logger.Info("Stock No: " + frame.Stock)
				Logger.Info("Length: " + frame.Length)
				Logger.Info(String.Format("Mass: {0}", frame.Mass))
				Logger.Info(String.Format("Volume: {0}", frame.Volume))
				Logger.Info(String.Format("Surface Area: {0}", frame.Area))	
				MassProps = Compdef.Document.ComponentDefinition.MassProperties
				Dim adPrincipleMoments(0 To 2) As Double
				Call MassProps.PrincipalMomentsOfInertia(adPrincipleMoments(0),adPrincipleMoments(1),adPrincipleMoments(2))
				Logger.Info(String.Format("Ixx: {0}", adPrincipleMoments(0)))
				Logger.Info(String.Format("Iyy: {0}", adPrincipleMoments(1)))
				Logger.Info(String.Format("Izz: {0}", adPrincipleMoments(2)))
		'Check if its a standard 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
Private Sub ResetItemCheck(BOMRows As BOMRowsEnumerator)
	'The purpose of this sub it to create and reset a property at 0 that will be used to determine if a part has already been renumbered
	'Iterate through the contents of the BOM Row
	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)
		Try
			CompDef.Document.PropertySets.Item(4).Item("PartSet").Value = 0
		Catch
			CompDef.Document.PropertySets.Item(4).Add(Row.ItemQuantity, "PartSet")
		End Try
		If Not Row.ChildRows Is Nothing Then
			ResetItemCheck(Row.ChildRows)
		End If
	Next
End Sub
	

 

0 Likes
Reply
294 Views
3 Replies
Replies (3)

roy7BB24
Advocate
Advocate

My apologies folks, I cracked it myself, as your were. I think

0 Likes

A.Acheson
Mentor
Mentor

What about looping through faces of the matching occurrences and if the features are on a different face then they are different parts. You could also check the first edge position of the feature it will be different. This might be rhe easier solution.

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

roy7BB24
Advocate
Advocate

I think if I can't get the results, I'm looking for that might be the next avenue I go down, the problems I was hitting when I was testing this method mainly came from I was looking at the iproperty COG properties of the part in the assembly, which apparently is a different number to what's shown if you open the part on its own look at the properties there. The script was opening every part and giving the "part only" COG properties. The beauty of this method is that I can tell if a part is identical but orientated about a different plane, and with any luck it should be as simple as rounding the COG properties to 0.001 (or there abouts), and then checking to see if 5 of 6 are identical then its a match. I think it will come down to testing though as when I'm dealing with tubelaser cut parts there can be a ton of features so on each part so it's going to be a case of guess and check I think

0 Likes