I'm using virtual parts in an assembly for some of the elements that I don't need any visual representation for. I'm trying to control the material property using ilogic. I'm using the same snippet I would use for a typical .ipt ,iproperties.materialofcomponent("part:1"). This code doesn't seem to have any effect on virtual parts. the rule runs with no errors, but does nothing. I can manually change the material by right-clicking in the model browser, but I'm trying to automate using ilogic. Is there an alternative way of driving the material that may work for a virtual component?
Solved! Go to Solution.
Solved by jdkriek. Go to Solution.
Note sure there is a specific shortcode for doing this, but I'm oldschool 😉
If you only have one VirtualComponent or know it's occurrence in the Assy:
Dim oAssDoc As AssemblyDocument: oAssDoc = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition: oAssDef = oAssDoc.ComponentDefinition ' Define Comp Def Dim oVirt As VirtualComponentDefinition ' Which Occurrence oVirt = oAssDef.Occurrences(1).Definition 'Change Material oVirt.Material.Name = "NameOFYourMaterial"
Or you can specify the name and loop through the Assembly:
Dim oAssDoc As AssemblyDocument: oAssDoc = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition: oAssDef = oAssDoc.ComponentDefinition ' virtual component Dim sName As String: sName = "VirtualComp" Dim oOccurrence As ComponentOccurrence For Each oOccurrence In oAssDef.Occurrences ' Look for virtual components If TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then ' Look for name match sNameS = Split(oOccurrence.Name, ":") If sName & ":" & sNameS(1) = oOccurrence.Name Then ' Define Comp Def Dim oVirt As VirtualComponentDefinition oVirt = oAssDef.Occurrences(1).Definition ' Change Material oVirt.Material.Name = "NameOFYourMaterial" End If End If Next
The code you sent where the occurance is known worked.I have the virtual components creating themselves automatically, so I won't be able to predict very easily which occurance I need. The loop idea would be ideal for what I'm doing, but I'm having trouble making it work. I'm getting an error (see below). Also, maybe you can help with another related issue. The virtual parts I'm creating are based on features in a single part. Need to loop through all features in a specific part, determine one at a time whether the feature is active and (if it is active) extract the feature's name. Any thoughts?
Error in rule: Rule36, in document: A_EB_bfd1door_cabinet_V2012_Concept.iam
Unable to cast COM object of type 'System.__ComObject' to interface type 'Inventor.VirtualComponentDefinition'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{D4652AC1-D4B9-4D65-8C2B-942D74411B1C}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
I did put my component name into the "Virtual component" area. I placed a message box into the "IF" statement displaying the virtual component name. That seemed to work, so it is finding the name. The section labeled "'define Comp Def" is where it gets stuck. Not sure if it matters, but i am running Inventor 2012.
The code is working fine in 2011-2013, but I think I may see what you are doing diffrently.
You are adding the Virtual Component through AddVirtual? Which would return a ComponentOccurrence.
So we should be doing Dim oVirt As ComponentOccurrence
Try this:
Dim oAssDoc As AssemblyDocument: oAssDoc = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition: oAssDef = oAssDoc.ComponentDefinition ' virtual component Dim sName As String: sName = "VirtualComp" Dim oOccurrence As ComponentOccurrence For Each oOccurrence In oAssDef.Occurrences ' Look for virtual components If TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then ' Look for name match sNameS = Split(oOccurrence.Name, ":") If sName & ":" & sNameS(1) = oOccurrence.Name Then ' Define Comp Def (As Occurrence) Dim oVirt As ComponentOccurrence oVirt = oAssDef.Occurrences(1).Definition ' Change Material oVirt.Material.Name = "NameOFYourMaterial" End If End If Next
Maybe getting somewhere, but still stuck.... It didn't work as is. It didn't seem to cooperate with with component occurence definition. I commented it out and tried some things below. It seems like it works in that if I insert the material into a message box immediately after assigning it appears correct, but when i right click on the virtual component to check it still shows as default. Also still shows as default on the BOM. Any thoughts?
Dim oAssDoc As AssemblyDocument: oAssDoc = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition: oAssDef = oAssDoc.ComponentDefinition ' virtual component Dim sName As String: sName = "Right_Side" Dim oOccurrence As ComponentOccurrence For Each oOccurrence In oAssDef.Occurrences ' Look for virtual components If TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then ' Look for name match sNameS = Split(oOccurrence.Name, ":") If sName & ":" & sNameS(1) = oOccurrence.Name Then MsgBox(oOccurrence.Name) ' Define Comp Def (As Occurrence) ' Dim oVirt As ComponentOccurrence ' oVirt = oAssDef.Occurrences(1).Definition ' ' Change Material ' oVirt.Material.Name = "Solid Wood" oAssDef.Occurrences(1).Definition.Material.Name = "Solid Wood" MsgBox(oAssDef.Occurrences(1).Definition.Material.Name) End If End If Next
Wierd, the code above works fine on my end.
See if this works. Start a new blank assy and run this rule on it.
Dim oAssDoc As AssemblyDocument = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition = oAssDoc.ComponentDefinition ' Virtual component Dim sName As String = "TestThis" Dim oMatrix As Matrix = ThisApplication.TransientGeometry.CreateMatrix ' Create a virtual oNewVirt = oAssDef.Occurrences.AddVirtual(sName, oMatrix) ' Set the material oNewVirt.Definition.Material.Name = "Solid Wood"
Weird, if i place it in a new assembly, it works fine. Here's the entire rule I'm using to create the virtual components. Maybe there's something in how I'm creating them giving problems. In this code its looking at features in a single part, testing whether the feature is active and creating a virtual component.
Dim oAsm As AssemblyDocument = ThisDoc.Document Dim oMatrix As Matrix = ThisApplication.TransientGeometry.CreateMatrix deleteall = New String(){"PUB_Left_Side", "PUB_Right_Side", "PUB_Top_Stretcher", "PUB_Top_Rear_Stretcher", "PUB_Full_Subtop", "PUB_Back", "PUB_Shelf_Hardwood_Edge", "PUB_Toe_Kick", "PUB_Right_Toe", "PUB_Left_Toe", "PUB_Rear_Toe", "PUB_Flush_Toe", "PUB_Sink_Apron", "PUB_Adjustable_Shelf"} For Each element In deleteall Try Component.InventorComponent(Replace(element, "PUB_", "") & ":1").delete Catch ex As exception End Try Next addactive = New String(){"PUB_Left_Side", "PUB_Right_Side", "PUB_Top_Stretcher", "PUB_Top_Rear_Stretcher", "PUB_Full_Subtop", "PUB_Back", "PUB_Shelf_Hardwood_Edge", "PUB_Toe_Kick", "PUB_Right_Toe", "PUB_Left_Toe", "PUB_Rear_Toe", "PUB_Flush_Toe", "PUB_Sink_Apron", "PUB_Adjustable_Shelf"} occur = 0 For Each element In addactive Try If Feature.IsActive("toplevel_notes", element) = True Then Try occur = occur + 1 Dim oOcc As ComponentOccurrence oOcc = oAsm.ComponentDefinition.Occurrences.AddVirtual(Replace(element, "PUB_", ""), oMatrix) Dim oCompDefVirtual As VirtualComponentDefinition = oOcc.Definition iProperties.Value(Replace(element, "PUB_", "") & ":1", "Custom", "Component_Width") = Parameter("toplevel_notes", Replace(element, "PUB_", "") & "_Wt") iProperties.Value(Replace(element, "PUB_", "") & ":1", "Custom", "Component_Length") = Parameter("toplevel_notes", Replace(element, "PUB_", "") & "_Lt") iProperties.Value(Replace(element, "PUB_", "") & ":1", "Custom", "Component_Thickness") = Parameter("toplevel_notes", Replace(element, "PUB_", "") & "_Th") iProperties.Value(Replace(element, "PUB_", "") & ":1", "Custom", "Part_Description") = Replace(Replace(element, "PUB_", ""), "_", " ") Catch ex As exception MessageBox.Show("Error in assigning " & element & " properties", "Warning!") End Try End If Catch ex As exception MessageBox.Show("The feature named " & element & " was not found.", "Warning!") End Try Next
a virtual part if active.
I am now seeing exactly what you are seeing and I have a solution!
Dim oAssDoc As AssemblyDocument = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition = oAssDoc.ComponentDefinition ' virtual component Dim sName As String = "Right_Side" Dim oOccurrence As ComponentOccurrence For Each oOccurrence In oAssDef.Occurrences ' Look for virtual components If TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then ' Look for name match sNameS = Split(oOccurrence.Name, ":") If sName & ":" & sNameS(1) = oOccurrence.Name Then MsgBox("We found the right one") ' Define Comp Def Dim oVirt As VirtualComponentDefinition oVirt = oOccurrence.Definition ' Change Material oVirt.Material.Name = "Solid Wood" MsgBox("Mat is " & oVirt.Material.Name) End If End If Next
We're past the error now with the revised code, but two problems I'm seeing now.... First, as its written the code should be only controlling one of the virtual components. For some reason it is assigning the property to all of my virtual components. Second, when I launch the bill of materials, the virtual components are no updated to match what shows when I right click on them to see the iproperties. Any thoughts?
Also, I'm a beginner at this stuff, so just double checking.....
The begining starts as Dim oAssDoc As AssemblyDocument = ThisApplication.ActiveDocument
If the item running this code were a child component in a much larger assembly would it still work properly. Plan is to have this rule triggered at times from a parent assembly.
Thanks again for all of your help.
Ok, I am pretty sure I've worked through the issues you are seeing.
The key is here:
' Change Material oVirt.Material = oAssDoc.Materials.Item("Solid Wood")
So the updated code would be:
Dim oAssDoc As AssemblyDocument = ThisApplication.ActiveDocument Dim oAssDef As AssemblyComponentDefinition = oAssDoc.ComponentDefinition ' virtual component Dim sName As String = "Right_Side" Dim oOccurrence As ComponentOccurrence For Each oOccurrence In oAssDef.Occurrences ' Look for virtual components If TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then ' Look for name match sNameS = Split(oOccurrence.Name, ":") If sName & ":" & sNameS(1) = oOccurrence.Name Then MsgBox("We found the right one") ' Define Comp Def Dim oVirt As VirtualComponentDefinition oVirt = oOccurrence.Definition ' Change Material oVirt.Material = oAssDoc.Materials.Item("Solid Wood") MsgBox("Mat is " & oVirt.Material.Name) End If End If Next