Pattern problem w/ multiple options

Pattern problem w/ multiple options

JohnKHouston
Advocate Advocate
1,302 Views
16 Replies
Message 1 of 17

Pattern problem w/ multiple options

JohnKHouston
Advocate
Advocate

Hi everyone,

 

I've been working on an assembly that uses patterns to determine how many drawers are in a cabinet. We have three different sizes, 7", 5", and 3". The largest starts on the bottom, then the middle drawer can be either the 3" or 5", and then finally the top drawer can be just the 3".

 

There are also 5 different lengths of slides that are inserted in each level that need to be controlled via suppression.

 

I can control the suppression of all the components in the first element based on criteria that the user selects but once the patterns are more than "1" element, I lose the ability to control the components easily.

 

What I'd like to do is somehow look at Element1 of the pattern and use that as the basis for the rest of the elements in the pattern, ie suppressed or not.

 

I've added a couple screen shots to help illustrate my problem. As can be seen in the cabinet pattern elements screen shot, Element2 of the MIDDLE DRAWER Pattern:1 shows some components that are not visible but should be suppressed so the BOM would be correct. The second screen shot is just to illustrate the options that I'm working with.

 

Any help with this would be greatly appreciated! Thanks in advance.

 

Best regards,

John

0 Likes
Accepted solutions (3)
1,303 Views
16 Replies
Replies (16)
Message 2 of 17

Anonymous
Not applicable

If I understand your question, you are wanting to suppress/unsupress all the elements in a pattern based on whether the first element is suppressed or not. If so, this code should work for you.

 

Dim oDoc As Document = ThisDoc.Document
Dim oDef As AssemblyComponentDefinition = oDoc.ComponentDefinition

For Each oPat As OccurrencePattern In oDef.OccurrencePatterns
	
	'For each occurrence in the pattern
	For Each oEle As OccurrencePatternElement In oPat.OccurrencePatternElements

		For Each oOcc As ComponentOccurrence In oEle.Occurrences
			
			Dim oSuppress As Boolean
			'Suppress of unsuppress all
			If oOcc.PatternElement.Index = 1 AndAlso oOcc.Suppressed = True Then
					
					oSuppress = True
					
			End If
			
			If oSuppress Then
				
				oOcc.Suppress
				
			Else
					
				oOcc.Unsuppress	
				
			End If
				
		Next

	Next

Next

 

0 Likes
Message 3 of 17

JohnKHouston
Advocate
Advocate

Hi Vincent,

 

Thanks for the reply, I appreciate you taking a look at this problem. Unfortunately I'm looking for something a bit more complicated than what you've suggested. I've added two screenshots that will hopefully explain my dilemma.

 

The two drawer cabinet shows the bottom drawer and middle drawer patterns. There's only 1 element and everything is suppressed by ilogic depending on the size of the drawer, D7, D5, or D3, and which slides will be used, 16/18/20/28.

 

The four drawer cabinet jpeg shows what happens when I add additional drawers. The patterns are controlled by parameters and the first element is still controlled by the ilogic rules, but the subsequent elements are not controlled by any code.

 

That's what I'd like to do, control the subsequent element components suppression with code. Not necessarily the whole element itself, just the components.

 

Hopefully that makes a little more sense what I'm trying to achieve.

 

two drawer cabinet.jpg

four drawer cabinet.jpg

0 Likes
Message 4 of 17

Anonymous
Not applicable

Ok I think I understand. You are making new elements in a pattern and you want the component suppression to be the same in subsequent elements. Try this 

Dim oDoc As Document = ThisDoc.Document
Dim oDef As AssemblyComponentDefinition = oDoc.ComponentDefinition


For Each oPat As OccurrencePattern In oDef.OccurrencePatterns
	
	Dim oOccList As List(Of Boolean) = New List(Of Boolean)

	For Each oEle As OccurrencePatternElement In oPat.OccurrencePatternElements

		For i = 1 To oEle.Occurrences.Count
			
			Dim oOcc As ComponentOccurrence = oEle.Occurrences.Item(i)
			
			If oOcc.PatternElement.Index = 1  Then
					
				oOccList.Add(oOcc.Suppressed)
				
			Else
				
				If oOccList(i-1) Then
					
					oOcc.Suppress
				
				Else
					
					oOcc.Unsuppress
					
				End If
					
			End If
	
		Next

	Next

Next
0 Likes
Message 5 of 17

WCrihfield
Mentor
Mentor

Try something like this.

It uses a NameValueMap to store the ReadOnly Boolean result of oOcc.Supressed by its index in the Occurrences collection (which should be the same for both elements.  I'm not sure if it will accept oOcc.Suppressed as the Value, but lets try it.  If it doesn't work, we can try specifying either True or False directly later.

Then uses that NameValueMap to check all other elements Occurrence.Suppressed state.  If they don't match, it changes the state of the Occurrence.

Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
Dim oPat As OccurrencePattern
Dim oEl As OccurrencePatternElement
Dim oOcc As ComponentOccurrence
Dim i, j As Integer
Dim oSupMap As NameValueMap
For Each oPat In oADef.OccurrencePatterns
'	If oPat.Name.Contains("MIDDLE DRAWER") Then
	For Each oEl In oPat.OccurrencePatternElements
		If oEl.Index = 1 Then
			'collect data about which occurrences are suppressed or not
			For i = 1 To oEl.Components.Count
				oOcc = oEl.Components.Item(i)
				oSupMap.Add(i, oOcc.Suppressed)
			Next
		End If
		If oEl.Index > 1 Then
			'Set suppressed status based on first element.
			For j = 1 To oEl.Components.Count
				oOcc = oEl.Components.Item(j)
				If oOcc.Suppressed <> oSupMap.Value(j) Then
					If oOcc.Suppressed = True And oSupMap.Value(j) = False Then
						oOcc.Unsuppress
					ElseIf oOcc.Suppressed = False And oSupMap.Value(j) = True Then
						oOcc.Suppress
					End If
				End If
			Next
		End If
	Next
Next

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 6 of 17

JohnKHouston
Advocate
Advocate

Hi Vincent,

 

This code seems to be working except for some reason one of the elements doesn't have the components visible. They're enabled, just not visible. Would you know what can be done to correct this? It's Element2 of the BOTTOM DRAWER Pattern.

 

Enabled component not visible.jpg

 

But, thanks very much for providing the code. It saves me a bunch of work!

0 Likes
Message 7 of 17

JohnKHouston
Advocate
Advocate

Hi WC,

 

I tried the code you provided but unfortunately I received an error that I didn't know how to resolve. The error message was; Object reference not set to an instance of an object.

 

Thanks for your help, I'm not sure if you would be able to debug the error from the message we got but I do appreciate your help with the code.

0 Likes
Message 8 of 17

Anonymous
Not applicable
Accepted solution

Try this. It will make all the components in the elements after the first visible and then suppress/unsuppress

 

Dim oDoc As Document = ThisDoc.Document
Dim oDef As AssemblyComponentDefinition = oDoc.ComponentDefinition


For Each oPat As OccurrencePattern In oDef.OccurrencePatterns
	
	Dim oOccList As List(Of Boolean) = New List(Of Boolean)

	For Each oEle As OccurrencePatternElement In oPat.OccurrencePatternElements

		For i = 1 To oEle.Occurrences.Count
			
			Dim oOcc As ComponentOccurrence = oEle.Occurrences.Item(i)
			
			If oOcc.PatternElement.Index = 1  Then
					
				oOccList.Add(oOcc.Suppressed)
				
			Else
				oOcc.Visible = True
If oOccList(i-1) Then oOcc.Suppress Else oOcc.Unsuppress
End If End If Next Next Next 

  

Message 9 of 17

WCrihfield
Mentor
Mentor

I modified how it gets and sets the values of the NameValueMap a bit.

See if this works now.

Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
Dim oPat As OccurrencePattern
Dim oEl As OccurrencePatternElement
Dim oOcc As ComponentOccurrence
Dim i, j As Integer
Dim oSupMap As NameValueMap
For Each oPat In oADef.OccurrencePatterns
'	If oPat.Name.Contains("MIDDLE DRAWER") Then
	For Each oEl In oPat.OccurrencePatternElements
		If oEl.Index = 1 Then
			'collect data about which occurrences are suppressed or not
			For Each oOcc In oEl.Components
				If oOcc.Suppressed = False Then
					oSupMap.Add(oOcc.Name, Boolean.FalseString)
				ElseIf oOcc.Suppressed = True Then
					oSupMap.Add(oOcc.Name, Boolean.TrueString)
				End If
			Next
		End If
		If oEl.Index > 1 Then
			'Set suppressed status based on first element.
			For Each oOcc In oEl.Components
				If oOcc.Suppressed <> CBool(oSupMap.Value(oOcc.Name)) Then
					If oOcc.Suppressed = True And CBool(oSupMap.Value(oOcc.Name)) = False Then
						oOcc.Unsuppress
					ElseIf oOcc.Suppressed = False And CBool(oSupMap.Value(oOcc.Name)) = True Then
						oOcc.Suppress
					End If
				End If
			Next
		End If
	Next
Next

 

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 10 of 17

JohnKHouston
Advocate
Advocate

Hi Vincent,

 

I'm not sure where the second set of code would go? Should it just be another rule that is called from the first code you sent?

 

Also, for some reason the code that you first sent is now throwing the "Object reference not set to an instance of an object" error message. I found a thread that suggested to use a msg box to see which line is causing the error. I tried that and found it pops up within one of the For Each statements. I'll post the code for you so you can see where the msg box is now showing up. I'm really surprised by this because it was working fine yesterday.

 

Here's a link to the thread that suggests how to find the line that is causing the error msg, https://forums.autodesk.com/t5/inventor-customization/ilogic-rule-object-reference-not-set-to-an-ins...

 

Thanks again for your help.

 

Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
Dim oPat As OccurrencePattern
Dim oEl As OccurrencePatternElement
Dim oOcc As ComponentOccurrence
Dim i, j As Integer
Dim oSupMap As NameValueMap
For Each oPat In oADef.OccurrencePatterns
'	If oPat.Name.Contains("MIDDLE DRAWER") Then
	For Each oEl In oPat.OccurrencePatternElements
		If oEl.Index = 1 Then
			'collect data about which occurrences are suppressed or not
			For i = 1 To oEl.Components.Count
				oOcc = oEl.Components.Item(i)
				oSupMap.Add(i, oOcc.Suppressed)
				MsgBox("Here")
			Next
		End If
		If oEl.Index > 1 Then
			'Set suppressed status based on first element.
			For j = 1 To oEl.Components.Count
				oOcc = oEl.Components.Item(j)
				If oOcc.Suppressed <> oSupMap.Value(j) Then
					If oOcc.Suppressed = True And oSupMap.Value(j) = False Then
						oOcc.Unsuppress
					ElseIf oOcc.Suppressed = False And oSupMap.Value(j) = True Then
						oOcc.Suppress
					End If
				End If
			Next
		End If
	Next
Next

  

0 Likes
Message 11 of 17

JohnKHouston
Advocate
Advocate

Hi  WCrihfield,

 

I tried the new code and it's still throwing the error msg. I tried the same troubleshooting that I did for the other code and I've pasted where the error comes before the msg box.

 

Maybe it's something I've done because both sets of code are now showing that error message? Anyway, thanks for your efforts to help solve my problem!

 

 

 

 

Dim oADoc As AssemblyDocument = ThisApplication.ActiveDocument
Dim oADef As AssemblyComponentDefinition = oADoc.ComponentDefinition
Dim oPat As OccurrencePattern
Dim oEl As OccurrencePatternElement
Dim oOcc As ComponentOccurrence
Dim i, j As Integer
Dim oSupMap As NameValueMap
For Each oPat In oADef.OccurrencePatterns
'	If oPat.Name.Contains("MIDDLE DRAWER") Then
	For Each oEl In oPat.OccurrencePatternElements
		If oEl.Index = 1 Then
			'collect data about which occurrences are suppressed or not
			For Each oOcc In oEl.Components
				If oOcc.Suppressed = False Then
					oSupMap.Add(oOcc.Name, Boolean.FalseString)
					MsgBox("Here")
				ElseIf oOcc.Suppressed = True Then
					oSupMap.Add(oOcc.Name, Boolean.TrueString)
				End If
			Next
		End If
		If oEl.Index > 1 Then
			'Set suppressed status based on first element.
			For Each oOcc In oEl.Components
				If oOcc.Suppressed <> CBool(oSupMap.Value(oOcc.Name)) Then
					If oOcc.Suppressed = True And CBool(oSupMap.Value(oOcc.Name)) = False Then
						oOcc.Unsuppress
					ElseIf oOcc.Suppressed = False And CBool(oSupMap.Value(oOcc.Name)) = True Then
						oOcc.Suppress
					End If
				End If
			Next
		End If
	Next
Next

 

0 Likes
Message 12 of 17

Anonymous
Not applicable

You can just replace my original code with my second post. Also the code you posted is WCrihfield's code not mine.

0 Likes
Message 13 of 17

JohnKHouston
Advocate
Advocate

Oh, I did do that...sorry! Too much going on. I'll double check my work then, probably my error somewhere.

0 Likes
Message 14 of 17

JohnKHouston
Advocate
Advocate

Okay, I got my sh!t sorted out.  🙂

 

The first code works correctly, same as yesterday but the second code you posted throws an error message. I've copied the more info tab but I doubt that will help you much. It's a pretty vague message.

 

System.Runtime.InteropServices.COMException (0x80004005): Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Inventor.ComponentOccurrence.set_Visible(Boolean )
at ThisRule.Main()
at Autodesk.iLogic.Exec.AppDomExec.ExecRuleInAssembly(Assembly assem)
at iLogic.RuleEvalContainer.ExecRuleEval(String execRule)

0 Likes
Message 15 of 17

JohnKHouston
Advocate
Advocate

Hi Vincent,

 

Sorry to bombard you with posts!  😁  I just wanted to let you know that I solved the issue. I just moved the 

oOcc.Visible = True

to after the Else, o0cc.Unsuppress statement and it worked fine. I think the issue was the visible=true statement was called while the components were still suppressed.

 

So, everything is working great! Thanks again for your help.

 

Best regards,

John

0 Likes
Message 16 of 17

Anonymous
Not applicable
Accepted solution

EDIT: Seems you solved it yourself, but I'll leave this here for anyone interested.

 

Try this instead. If components are already suppressed trying to make them visible throws an error. Now it will only make them visible if they are unsuppressed

 

Dim oDoc As Document = ThisDoc.Document
Dim oDef As AssemblyComponentDefinition = oDoc.ComponentDefinition

For Each oPat As OccurrencePattern In oDef.OccurrencePatterns
	
	Dim oOccList As List(Of Boolean) = New List(Of Boolean)

	For Each oEle As OccurrencePatternElement In oPat.OccurrencePatternElements

		For i = 1 To oEle.Occurrences.Count
			
			Dim oOcc As ComponentOccurrence = oEle.Occurrences.Item(i)
			
			If oOcc.PatternElement.Index = 1  Then
					
				oOccList.Add(oOcc.Suppressed)
				
			Else
				
				If oOccList(i-1) Then
					
					oOcc.Suppress
				
				Else
					
					oOcc.Unsuppress
					oOcc.Visible = True
					
				End If
					
			End If
	
		Next

	Next

Next

 

 

0 Likes
Message 17 of 17

JohnKHouston
Advocate
Advocate
Accepted solution

I wanted to notate that the correct code had to have one small correction for it to work correctly. I accepted Vincent's previous suggestion because it is (mostly) correct.

 

Here's the corrected code:

 

Dim oDoc As Document = ThisDoc.Document
Dim oDef As AssemblyComponentDefinition = oDoc.ComponentDefinition


For Each oPat As OccurrencePattern In oDef.OccurrencePatterns
	
	Dim oOccList As List(Of Boolean) = New List(Of Boolean)

	For Each oEle As OccurrencePatternElement In oPat.OccurrencePatternElements

		For i = 1 To oEle.Occurrences.Count
			
			Dim oOcc As ComponentOccurrence = oEle.Occurrences.Item(i)
			
			If oOcc.PatternElement.Index = 1  Then
					
				oOccList.Add(oOcc.Suppressed)
				
			Else
				
				If oOccList(i-1) Then
					
					oOcc.Suppress
				
				Else
					
					oOcc.Unsuppress

oOcc.Visible = True
End If End If Next Next Next
0 Likes