Creating a virtual component for each model states and giving it mass

Creating a virtual component for each model states and giving it mass

will.astill
Advocate Advocate
436 Views
7 Replies
Message 1 of 8

Creating a virtual component for each model states and giving it mass

will.astill
Advocate
Advocate

I'm trying to replicate an annoying feature of some of our client's BoM's on multi-assembly drawings. They use a REALLY annoying format for multi assembly BoM (see image).

 

For the last two years we've used all sorts of fudges with a mix of sketch symbols and manual BoM overrides but it's horrible so I'm looking to make something better.

 

The solution I've come up with (that works 100% if I do it manually) is to:

  1. [Assy] Create a model state called [Primary] that contains a virtual component for each configuration and has everything else supressed.
  2. [Assy] Set the relevant iProps in each virtual component to match the model state iProps (part number, stock number (what we use for part number), description etc.
  3. [Dng] Drop in base views for each model state and then insert a parts list for each, using a style with a header for the [Primary] and a style with no header (the red boxes) for the sub parts.

This is way better on the drawing, because I only have to hide a couple of rows and update a couple of columns with static values, but it’s a faff so I’m trying to automate.

willastill_0-1736597464607.png

 

willastill_1-1736597464609.png

 

willastill_2-1736597464610.png

 

I’m “low to moderate” with iLogic but I’ve gathered up a load of code snippets and put something together that is working ok.

Only problem is that when I try to add the mass properties to the virtual components I get really strange behaviour – it’s row 98 in the attached code.

 

For some reason the masses don't update to be correct, instead they are like 6 x the value they should be. I'm wondering if I need to use a different line to get the mass just for the model state or something?

willastill_3-1736597464615.png

 

Note, the code's a work in progress and I'm enjoying working on it and learning - just spending an unreasonable amount of time on this mass issue so wanted to ask for some help 😞

 

I’ve attached the full code below for review – is anyone able to help me out with what I’m doing wrong?

0 Likes
437 Views
7 Replies
Replies (7)
Message 2 of 8

will.astill
Advocate
Advocate
'''Code to fudge the BoM such that the assembly parts list looks how we want it to look.
'''i.e. the parts list will contain item 1 that has the assembly in it.

Sub Main()
	
	'Create an object for the current document and terminate if this isn't an assembly doc.
	oDoc = ThisDoc.ModelDocument
	If oDoc.DocumentType <> kAssemblyDocumentObject Then Exit Sub

	'ThisApplication.ScreenUpdating = False	'Leave turned off until error trapping is sorted!

	'Get the assembly definitions
	Dim oAssDef As AssemblyComponentDefinition 
	oAssDef = oDoc.ComponentDefinition 
	
	'Get the model states in the document
	Dim oStates As ModelStates
	oStates = oAssDef.ModelStates
	
	Dim oTable As ModelStateTable			'Not sure how this is different from the ModelState - to look at later and see if the loop can improve.
	oTable = oStates.ModelStateTable
	
	Dim oStateRow As ModelStateTableRow		'Not sure if necessary
	Dim oCurrentState As ModelState
	
	'Store the current model state so we can return to it later.
	oCurrentState = oStates.ActiveModelState
	
	'Loop through the model states
	For Each oStateRow In oTable.TableRows
		If oStateRow.MemberName = "[Primary]" Then Continue For	'Not bothered about the primary state for now.
		oStates.Item(oStateRow.Index()).Activate				'If it's not, then activate the model state.
			
			'Get all the details we want about the part...
			Dim iProps As PropertySet			
			Dim sPN, sDesc, sSN As String
			Dim dMass As Double
					
					'And the information in the design tracking properties collection.
					iProps =  oDoc.PropertySets.Item("Design Tracking Properties")
					If iProps IsNot Nothing Then
						sPN = iProps.Item("Part Number").Value.ToString()
						sSN = iProps.Item("Stock Number").Value.ToString()
						sDesc = iProps.Item("Description").Value.ToString()
					End If		
					
					dMass = oStates.ActiveModelState.Document.ComponentDefinition.MassProperties.Mass	'Store the mass of the assembly n this configuration.
		
			'Set the name of the virtual part to be the description of the part from the iProperties.
			NameOfVirtualPart = sDesc
			
			Dim virtComponent As ComponentOccurrence = Nothing	'Container for the virtual parts
			
			'Check if a virtual part with this description aleady exists.
			For Each co As ComponentOccurrence In oAssDef.Occurrences
				If co.Name.ToString = NameOfVirtualPart & ":1" Then		'And if it does...
					virtComponent = co									'assign that object to the virtComponent object for later use
					Exit For											'and stop wasting everyone's time!
				End If
			Next
			
			'If nothing was found, create a new virtual component with the iProperty description as it's name..
			If IsNothing(virtComponent) Then
				virtComponent = oAssDef.Occurrences.AddVirtual(NameOfVirtualPart, ThisApplication.TransientGeometry.CreateMatrix) 
			End If
				
			'Now set the properties accordingly.
			virtComponent.Definition.PropertySets.Item("Design Tracking Properties").Item("Part Number").Value = sPN
			virtComponent.Definition.PropertySets.Item("Design Tracking Properties").Item("Stock Number").Value = sSN
			virtComponent.Definition.PropertySets.Item("Design Tracking Properties").Item("Description").Value = sDesc
					
			'And then set this item to be item 1 in the BoM
			Dim oBOM As BOM = oAssDef.BOM
			Dim oView As BOMView = oBOM.BOMViews.Item(2)
			Dim pRow As BOMRow
			
			oBOM.StructuredViewEnabled = True
			
			'find BOM row that relates to the virtual component we just created
			For Each oRow As BOMRow In oView.BOMRows							'Loop through the BoM
				If oRow.ComponentDefinitions(1) Is virtComponent.Definition		'Compare the item definition with that of the virtual component
					pRow = oRow													'And if it's the same, remember the row
					Exit For													'Then stop wasting time
				End If
			Next
				
			If Not pRow Is Nothing Then 										'If we found the item in the BoM
				If pRow.ItemNumber <> 1 Then									'And if it's not already item 1
					For Each oRow As BOMRow In oView.BOMRows					'switch the numbers of the parts
						If IsNumeric(oRow.ItemNumber) Then						'ignoring any alpha rows
							If oRow.ItemNumber = 1 Then oRow.ItemNumber = pRow.ItemNumber
						End If
					Next	
					pRow.ItemNumber = 1											'and set this item to item 1 (todo: will need to be a counter for item 2, 3 etc.)
				End If
				
				pRow.TotalQuantity = 0											'Set this to be a zero quantity part (in the hope that this means it won't affect the assembly mass when I give it a mass)
				'virtComponent.MassProperties.Mass = dMass						'Problem here... assigning the assembly mass to the virtual component results in wierd behaviour
			End If
			
			oView.Sort("Item")													'Now sort the BoM
			
	Next
	
	oCurrentState.Activate			'Reset the model state to the starting condition to be tidy.
	
	'ThisApplication.ScreenUpdating = True
End Sub
0 Likes
Message 3 of 8

will.astill
Advocate
Advocate

OK! I thought I'd post an update in case anyone is discovering this in the future and wants to know the answer.

I've spent all weekend on it, running trials and.....

 

I think it is a bug in Inventor - I'm using 2025.2.1 - build 293.

 

Inventor isn't ignoring the mass of supressed parts when it makes the mass calculations - if the part is a virtual component.

 

To recreate the issue:

In the attached model files, there is a virtual component and a real component.

If you set the mass of the virtual component to zero and record the mass of the assembly it is 0.008kg.

Then manually set the mass of the virtual component (Unsuppress, iProps, Physical and type into the Mass box) to 0.1Kg.

Check the mass of the assembly - it is 0.108Kg as expected.

Then supress the virtual component.

Check the mass of the assembly - it is still 0.108Kg.

 

That's different behaviour to if the "real part" is suppressed, in which case it's mass is no longer included in the calculations.

 

Is this expected behaviour?

 

 

 

0 Likes
Message 4 of 8

_dscholtes_
Advocate
Advocate

Can confirm this behavior in Inventor 2023.5.2, build 446.

 

I don't expect suppressed virtual components to be counted as part of the total mass.
Especially when Inventor tells me that suppressed components will not be part of the BOM when I (un)suppress them.

Not part of the BOM, not part of the mass, right?

 

0 Likes
Message 5 of 8

will.astill
Advocate
Advocate

Agreed. And it's the opposite of the behaviour everywhere else too.

 

How do I raise it with the dev team? It's clearly a bug.

0 Likes
Message 6 of 8

will.astill
Advocate
Advocate

@johnsonshiue - This is still bugging me as it's clearly something wrong with the code somewhere.

 

You always seem to be very helpful with these things - how do I raise it as a bug that needs sorting?

 

TLDR: The issue is that the mass of virtual components seems to be taken into account in the calculation for assembly mass. Even when they are suppressed.

0 Likes
Message 7 of 8

WCrihfield
Mentor
Mentor

In the mean time, you may be able to include setting the BOMStructure status to help with controlling things in the BOM.  There is something in the 'Document Settings' for this, and also a setting of the CompoentOccurrence for this (ComponentOccurrence.BOMStructure), for overriding the document level setting.

ComponentDefinition.BOMStructure 

Before ModelStates, we used to use 'visibility' (hiding) along with BOMStructure to manage stuff like this, instead of Suppression.  In the drawing, we could filter our Parts List by the DVR (DesignViewRepresentation) of the assembly, and the BOMStructure settings took care of the rest.  We did not like LOD (LevelOfDetailRepresentations) that much, due to certain restrictions...and still only use ModelStates whenever absolutely necessary, for similar reasons.  They tend to introduce all sorts of adverse issues, and make interacting with those documents by code far more complex.

By the way, the BOMRow.ItemNumber property says that its value is a String (not Integer), so attempting to do mathematical operations directly with its value may not work out that well, and may require intermediate Type conversion(s).  We very rarely use 'virtual' components in our assemblies though, so setting 'Mass' to one is not something that I am particularly experienced with, but just wanted to make sure you were aware of the 'units' expected there.  It did not look like you were attempting to convert units in your earlier code examples, so this may not be an issue, but that MassProperties.Mass property is expecting 'database units' value, which may be different than the 'document units'.  Something else you may need to be aware of is that some ModelStates may not have a 'Document' associated with them (ModelState.Document).  Generally, that property only gets a value set to it after you have placed an instance/occurrence of it into an assembly, as a component occurrence.  At that moment, it generates the Document for that ModelState to include in the assembly, for that occurrence.  If the ModelState was just created manually, or by code, within its main 'File', and there has never been an instance/occurrence of it placed in an assembly, then that property (Document) may not have a value yet, so it may be 'Nothing'.  Always check that, to be safe.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 8 of 8

will.astill
Advocate
Advocate

Thank you Wesley.

 

I've kind of parked this for the moment as I was spending ages on it and it didn't seem to be going anywhere but when I come back to it in Inventor 3000 (or whenever the issue gets fixed) I'll get my head around everything again and hopefully your comments will make sense to me! As I said in the original post, my iLogic experience relies heavily on Chat GPT and forum code snippets 😄

 

Thanks again for engaging, it's more than I've managed to get out of the Inventor team so far!

0 Likes