Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.
Ralf_Krieg
in reply to: rikard.nilsson

Hello

 

How do you get the part position relativ to assembly space? If you've created a proxy object, then I think you can also get the angles from there. If you save data to part parameters, what about a part occurs multiple times in your assembly? Which position will be saved?

Can you try this iLogic version?

 

 

Sub Main
	Dim oAssDoc As Inventor.AssemblyDocument = ThisDoc.Document 
	GetAngleOfOccurence(oAssDoc.ComponentDefinition.Occurrences)
End Sub

' a few helper functions...

 Private Function Atan2(y As Double, x As Double)
' returned value is in radians
    If x > 0 Then
        Atan2 = Atan(y / x)
    ElseIf (x < 0 And y >= 0) Then
        Atan2 = Atan(y / x) + PI
    ElseIf (x < 0 And y < 0) Then
        Atan2 = Atan(y / x) - PI
    ElseIf (x = 0 And y > 0) Then
        Atan2 = PI / 2
    ElseIf (x = 0 And y < 0) Then
        Atan2 = -PI / 2
    ElseIf (x = 0 And y = 0) Then
        Atan2 = 0
    End If
End Function

 Private Function EulerThree(trans() As Double) As Double
' returned value is in radians
    If (trans(8) <> 1 And trans(8) <> -1) Then
		EulerThree = Atan2(trans(4) / Cos(Asin(trans(8))), trans(0) / Cos(Asin(trans(8))))
    Else
        EulerThree = 0
    End If
End Function

Private Function EulerTwo(trans() As Double) As Double
' returned value is in radians
    If (trans(8) <> 1 And trans(8) <> -1) Then
		EulerTwo = -Asin(trans(8))
    ElseIf (trans(8) = -1) Then
        EulerTwo = PI / 2
    Else
        EulerTwo = -PI / 2
    End If
End Function

Private Function EulerOne(trans() As Double) As Double
' returned value is in radians
    If (trans(8) <> 1 And trans(8) <> -1) Then
		EulerOne = Atan2(trans(9) / Cos(Asin(trans(8))), trans(10) / Cos(Asin(trans(8))))
    ElseIf (trans(8) = -1) Then
        EulerOne = Atan2(trans(1), trans(2))
    Else
        EulerOne = Atan2(-trans(1), -trans(2))
    End If
End Function

Private Function EulerAngles(trans() As Double)
    'convert from radian to degree
    Dim eulers(2) As Double
    eulers(0) = EulerOne(trans) * 180 / PI
    eulers(1) = EulerTwo(trans) * 180 / PI
    eulers(2) = EulerThree(trans) * 180 / PI
    EulerAngles = eulers
End Function

'finally the function that retrieves the rotations:

Sub GetAngleOfOccurence(oOccs As ComponentOccurrences)
    ' Traverse all referenced occurences in the assembly
    For Each oOcc As ComponentOccurrence In oOccs
   		
		Dim trans(16) As Double
        Dim oMatrix As Matrix

		'is occurrence part or subassembly?
		If oOcc.DefinitionDocumentType = DocumentTypeEnum.kAssemblyDocumentObject Then
			GetAngleOfOccurence(oOcc.SubOccurrences)
		ElseIf oOcc.DefinitionDocumentType = DocumentTypeEnum.kPartDocumentObject Then
			Dim oOccProxy As ComponentOccurrenceProxy 
			oOcc.CreateGeometryProxy(oOcc,oOccProxy)
			
			oMatrix = oOccProxy.Transformation
			
	        ' insert point is in the matrix:
	        Call oMatrix.GetMatrixData(trans) ' get the matrix as an Array
			'test if we get an array..
	        If (Not trans Is Nothing And IsArray(trans)) Then
				Logger.Debug("")
				Logger.Debug(oOcc.Name)
	            Logger.Debug("Insert point (cm)")
				Logger.Debug("X=: " & Round(trans(3),2))
				Logger.Debug("Y=: " & Round(trans(7),2))
				Logger.Debug("Z=: " & Round(trans(11),2))
	        End If

			' invert matrix to get the parts transform in the assembly's coordinates
	        Call oMatrix.Invert
	       
	        ' be aware that retrieving the eulers from the matrix may not produce the result you would expect.
	        ' you should keep to the matrix if you can.
	       
	        Call oMatrix.GetMatrixData(trans) ' get the matrix as an Array
	        'test if we get an array..
	        If (Not trans Is Nothing And IsArray(trans)) Then
	            Dim result() As Double
	            result = EulerAngles(trans)
	            Logger.Debug( "Euler 1=: " & Round(result(0),2))
	            Logger.Debug ("Euler 2=: " & Round(result(1),2))
	            Logger.Debug ("Euler 3=: " & Round(result(2),2))
	        End If
		End If
	Next
End Sub

 

 


R. Krieg
RKW Solutions
www.rkw-solutions.com