iLogic - Update custom iproperties

iLogic - Update custom iproperties

jishee
Enthusiast Enthusiast
871 Views
7 Replies
Message 1 of 8

iLogic - Update custom iproperties

jishee
Enthusiast
Enthusiast

I have code that will create custom iproperties for width, length, and thickness based on the range box of the parts in an assembly. The code is below. It works fine the first time the rule is run but errors when it is rule again after a change is made to the model. How do I get this to run after an update has been made to the model.

 

Thank you.

 

'Set a reference to the assembly component definition.
'This assumes an assembly document is open.
Dim oAsmCompDef As AssemblyComponentDefinition
oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition

'Conversion factor cm to in
oCF = 0.393701

'Iterate through all of the occurrences
Dim oOccurrence As ComponentOccurrence
For Each oOccurrence In oAsmCompDef.Occurrences
'Check for and skip virtual components
If Not TypeOf oOccurrence.Definition Is VirtualComponentDefinition Then

  	oX = (oOccurrence.Definition.RangeBox.MaxPoint.X _
		- oOccurrence.Definition.RangeBox.MinPoint.X)*oCF
	oY = (oOccurrence.Definition.RangeBox.MaxPoint.Y _
		- oOccurrence.Definition.RangeBox.MinPoint.Y)*oCF
	oZ = (oOccurrence.Definition.RangeBox.MaxPoint.Z _
		- oOccurrence.Definition.RangeBox.MinPoint.Z)*oCF
	
	'Get middle number
	If oX > oY And oX < oZ Or oX > oZ And oX < oY Then 	
		oMiddle = oX
		GoTo Set_Width
	End If 
	
	If oY > oX And oY < oZ Or oY > oZ And oY < oX Then 
		oMiddle = oY
		GoTo Set_Width
	End If 
	
	If oZ > oX And oZ < oY Or oZ > oY And oZ < oX Then 
		oMiddle = oZ
		GoTo Set_Width
	End If 

	'Set Width
	Set_Width:
	iProperties.Value(oOccurrence.Name, "Custom", "Width") = Round(oMiddle,3)

	'Set Length
	iProperties.Value(oOccurrence.Name, "Custom", "Length") = Round(MaxOfMany(oX, oY, oZ),3)

	'Set Thickness
	iProperties.Value(oOccurrence.Name, "Custom", "Thickness") = Round(MinOfMany(oX, oY, oZ),3)

End If
Next

 

0 Likes
Accepted solutions (1)
872 Views
7 Replies
Replies (7)
Message 2 of 8

WCrihfield
Mentor
Mentor
Accepted solution

Try defining each variable and setting their values to default before loop begins like this.

'This assumes an assembly document is open.
Dim oADef As AssemblyComponentDefinition = ThisApplication.ActiveDocument.ComponentDefinition

'Conversion factor cm to in
Dim oCF As Double = 0.393701
Dim oX As Double = 0
Dim oY As Double = 0
Dim oZ As Double = 0
Dim oMiddle As Double = 0
Dim oOcc As ComponentOccurrence = Nothing
'Iterate through all of the occurrences
For Each oOcc In oADef.Occurrences
	'Check for and skip virtual components
	If Not TypeOf oOcc.Definition Is VirtualComponentDefinition Then
	  	oX = (oOcc.Definition.RangeBox.MaxPoint.X _
			- oOcc.Definition.RangeBox.MinPoint.X)*oCF
		oY = (oOcc.Definition.RangeBox.MaxPoint.Y _
			- oOcc.Definition.RangeBox.MinPoint.Y)*oCF
		oZ = (oOcc.Definition.RangeBox.MaxPoint.Z _
			- oOcc.Definition.RangeBox.MinPoint.Z)*oCF
		'Get middle number
		If oX > oY And oX < oZ Or oX > oZ And oX < oY Then 	
			oMiddle = oX
			GoTo Set_Width
		End If 
		If oY > oX And oY < oZ Or oY > oZ And oY < oX Then 
			oMiddle = oY
			GoTo Set_Width
		End If 
		If oZ > oX And oZ < oY Or oZ > oY And oZ < oX Then 
			oMiddle = oZ
			GoTo Set_Width
		End If 
		Set_Width:
		iProperties.Value(oOcc.Name, "Custom", "Width") = Round(oMiddle,3)
		iProperties.Value(oOcc.Name, "Custom", "Length") = Round(MaxOfMany(oX, oY, oZ),3)
		iProperties.Value(oOcc.Name, "Custom", "Thickness") = Round(MinOfMany(oX, oY, oZ),3)
	End If
Next

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 3 of 8

jishee
Enthusiast
Enthusiast

Works perfect now. Thanks for your help!

Message 4 of 8

R_Cygan
Participant
Participant

This is great, working well on NON round parts,

but

I have few parts, round profiles,  When the NON round parts  are above in the browser - the rule returns incorrect values = the width of the ROUND  parts are same as the first NON round part,

R_Cygan_0-1701355243319.pngR_Cygan_1-1701355300396.png

 

All is GOOD= the width is "0" when the Round parts are above NON round parts in the browser 

 

R_Cygan_2-1701355433966.png  

R_Cygan_3-1701355491530.png

 

Thank You in advance

 

 

 

 

0 Likes
Message 5 of 8

R_Cygan
Participant
Participant

This is great, working well on NON round parts,

but

I have few parts, round profiles,  When the NON round parts  are above in the browser - the rule returns incorrect values = the width of the ROUND  parts are same as the first NON round part,

R_Cygan_0-1701355721980.png

 

R_Cygan_1-1701355722181.png

 

 

All is GOOD= the width is "0" when the Round parts are above NON round parts in the browser 

 

R_Cygan_2-1701355722067.png

 

  

R_Cygan_3-1701355722065.png

 

 

Thank You in advance

0 Likes
Message 6 of 8

R_Cygan
Participant
Participant

Hi, I am not familiar with I-logic codes = this seams to be advance

 

We need also need to define:

1. The ENDs condition of the part = the (cut) angle

2. If the part is hollow ( non Solid Bar ) need to define the wall thickness

 

Can be this done?

Most appreciated

0 Likes
Message 7 of 8

WCrihfield
Mentor
Mentor

Hi @R_Cygan.  The suggestion I made 2 1/2 years ago was not that great.  The assembly may have simply needed to be updated before running the rule again, but I am not sure.  When you declare variables that you are going to use within a loop, before the start of the loop, that can improve performance, but it can also cause problems with the values of those variables being carried over from the end of the previous loop to the start of the next loop, if not handled properly.  Below is an updated iLogic rule for the same exact task, but it uses a few different tactics, as listed below:

  • Updates the assembly before the loop, to ensure everything is up to date after any recent changes
  • ComponentOccurrence.OrientedMinimumRangeBox property (newly available in 2024) to get the components OrientedBox (instead of a regular Box), then uses its 'Direction#.Length' for the 3 size values, to be more accurate.
  • List(Of Double) Type variable
    • And its Sort method, to determine which values to use for which labels.
      • After calling the Sort method, the List entries are sorted from smallest at the top/start, to largest at the bottom/end.
    • When using a List for numerical values, we can also utilize its extension methods List.Min and List.Max
    • And even though the List is declared / created before the start of the loop, it is being 'cleared' just inside the loop, to ensure no previous values get carried over to the new results.
  • Updates the assembly after the loop, to make sure the changes to the component properties get registered, and any reactions that need to happen, get done.
  • Code for saving the assembly afterwards is commented out, because that step is not always desired.
Sub Main
	If ThisDoc.Document.DocumentType <> DocumentTypeEnum.kAssemblyDocumentObject Then Exit Sub
	Dim oADoc As AssemblyDocument = ThisDoc.Document
	If oADoc.RequiresUpdate Then oADoc.Update2(True) 'just making sure everything is updated first
	Dim oOccs As ComponentOccurrences = oADoc.ComponentDefinition.Occurrences
	Dim oSizes As New List(Of Double)
	For Each oOcc As ComponentOccurrence In oOccs
		oSizes.Clear 'clear contents of list so no values from last loop carry over
		Dim oOBox As OrientedBox = Nothing 'reset
		oOBox = oOcc.OrientedMinimumRangeBox
		oSizes.Add(oOBox.DirectionOne.Length)
		oSizes.Add(oOBox.DirectionTwo.Length)
		oSizes.Add(oOBox.DirectionThree.Length)
		oSizes.Sort() 'sorts List entries by value (smallest first, largest last)
		iProperties.Value(oOcc.Name, "Custom", "Thickness") = Round(oSizes.Item(0), 3) 'or oSizes.Min
		iProperties.Value(oOcc.Name, "Custom", "Width") = Round(oSizes.Item(1), 3) 'middle entry
		iProperties.Value(oOcc.Name, "Custom", "Length") = Round(oSizes.Item(2), 3) 'or oSizes.Max
	Next
	If oADoc.RequiresUpdate Then oADoc.Update2(True)
	'If oADoc.Dirty Then oADoc.Save2(True)
End Sub

However, those last two requests, about end treatments and wall thickness is something that will most likely need to be handled at the part level, instead of from the assembly level, because there are simply way to many design techniques and variations in how things can be designed to accurately collect that type of data from random assembly components, without having a lot of 'inside' knowledge about those components.  If I was very familiar with how all the parts involved were designed, and I knew that all of the 'hollow' parts were designed a very specific way, and had consistently named user parameters for those aspects of their design, then that might be possible, but would still likely increase the size and complexity of a code like this a lot, and would likely be custom to those specific designs.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

0 Likes
Message 8 of 8

R_Cygan
Participant
Participant

Thx,
Not sure why, but after changes to the parts the code is not updating the values in  custom I Properties

0 Likes