Get Transformation Matrix from UCS

Get Transformation Matrix from UCS

eadonan
Enthusiast Enthusiast
1,603 Views
3 Replies
Message 1 of 4

Get Transformation Matrix from UCS

eadonan
Enthusiast
Enthusiast

For an Assembly *.iam, I need to retrieve the 4X4 transformation matrix between two UCSs. I've cobbled together some code from various places including this forum, but I'm unable to derive the correct parameters. I tried a couple of iLogic examples, but I've not been successful. The below VBA code is as close as I've got. I have some .NET experience, but I'm new to VBA and iLogic concepts. I need the 4X4 matrix for each of 6 sensors in relation to the reference UCS. This is likely a one-time deal, so I don't need anything too fancy like file outputs. Just something I can screenshot for documentation.

The "from" UCS will be based on user selection and the part will have a single UCS. The "to" UCS is based in the Assembly and is also intended to only have a single UCS.

Sub GetTransformParameters()
    
    Dim oDoc As AssemblyDocument
    Set oDoc = ThisApplication.ActiveDocument
    
    Dim oDef As AssemblyComponentDefinition
    Set oDef = oDoc.ComponentDefinition

    'Select UCS from Part
    Dim oUCS_From As UserCoordinateSystem
    Set oUCS_From = ThisApplication.CommandManager.Pick(kUserCoordinateSystemFilter, "Select Sensor (""From"") UCS")
    
    'Select USC from Assembly - Currently there is only 1 and its Named: UCS_Reference
    Dim oUCS_To As UserCoordinateSystem
    Set oUCS_To = oDef.UserCoordinateSystems.Item(1)
    
    'Get the PartComponentDefinition in order to get the transformation necessary to create a matrix
    Dim occDef As ComponentDefinition
    Set occDef = oUCS_From.Parent
    
    Dim occ As ComponentOccurrence
    Dim occMatrix As Matrix
    
    For Each occ In oDef.Occurrences
        If occ.Definition Is occDef Then
            Set occMatrix = occ.Transformation
        End If
    Next
        
    Dim oMatrix_From As Matrix
    Set oMatrix_From = oUCS_From.Transformation
    'Call oMatrix_From.TransformBy(occMatrix) ' Commented out from uncertainty
    
    Dim oMatrix_To As Matrix
    Set oMatrix_To = oUCS_To.Transformation
    Call oMatrix_To.TransformBy(occMatrix)
    
    
    Dim oOrigin1 As Point
    Dim oXAxis1 As Vector
    Dim oYAxis1 As Vector
    Dim oZAxis1 As Vector
    ' Get the CS as origin point and axis vectors for oMatrix1
    Call oMatrix_From.GetCoordinateSystem(oOrigin1, oXAxis1, oYAxis1, oZAxis1)
    
    Dim oOrigin2 As Point
    Dim oXAxis2 As Vector
    Dim oYAxis2 As Vector
    Dim oZAxis2 As Vector
    ' Get the CS as origin point and axis vectors for oMatrix2
    Call oMatrix_To.GetCoordinateSystem(oOrigin2, oXAxis2, oYAxis2, oZAxis2)
    
    Dim oMatrix As Matrix
    ' Create new 4X4 Matrix object and initialize as identity
    Set oMatrix = ThisApplication.TransientGeometry.CreateMatrix
    ' Set oMatrix to transform "from" oUCS_From "to" oUCS_To
    Call oMatrix.SetToAlignCoordinateSystems(oOrigin1, oXAxis1, oYAxis1, oZAxis1, oOrigin2, oXAxis2, oYAxis2, oZAxis2)
    ' Use Print to view resulting 4X4 transformation matrix
    Debug.Print (Format(oMatrix.Cell(1, 1), "0.00000") & " " & Format(oMatrix.Cell(1, 2), "0.00000") & " " & Format(oMatrix.Cell(1, 3), "0.00000") & " " & Format(oMatrix.Cell(1, 4), "0.00000"))
    Debug.Print (Format(oMatrix.Cell(2, 1), "0.00000") & " " & Format(oMatrix.Cell(2, 2), "0.00000") & " " & Format(oMatrix.Cell(2, 3), "0.00000") & " " & Format(oMatrix.Cell(2, 4), "0.00000"))
    Debug.Print (Format(oMatrix.Cell(3, 1), "0.00000") & " " & Format(oMatrix.Cell(3, 2), "0.00000") & " " & Format(oMatrix.Cell(3, 3), "0.00000") & " " & Format(oMatrix.Cell(3, 4), "0.00000"))
    Debug.Print (Format(oMatrix.Cell(4, 1), "0.00000") & " " & Format(oMatrix.Cell(4, 2), "0.00000") & " " & Format(oMatrix.Cell(4, 3), "0.00000") & " " & Format(oMatrix.Cell(4, 4), "0.00000"))

End Sub

I'm expecting the output to be something similar to the below. The translation portion of the matrix is in meters.

0.17348 -0.04339 0.98387 0.35579
0.00755 0.99905 0.04273 -0.00869
-0.98480 0.00002 0.17365 0.16036
0.00000 0.00000 0.00000 1.00000

 

But I'm getting the following output. I'm sure it isn't correct, but It may help someone find my issue. I'm assuming the translation parameters are in cm. 

0.00000 0.17365 0.98481 22.95727
-0.17365 0.96985 -0.17101 5.76088
-0.98481 -0.17101 0.03015 -13.26167
0.00000 0.00000 0.00000 1.00000

 

Thanks,

Eric

0 Likes
1,604 Views
3 Replies
Replies (3)
Message 2 of 4

erichter
Advocate
Advocate

By default, Inventor's API works in centimeters. You need to convert them to the units of the document that you are using. I found that it was easier to convert the matrix into an array and then use a for loop to convert only values in the the 4th column in the matrix, and the for loop can also round all of the values as well. I modified the code after the matrix was defined. I also changed the degug.print to a MsgBox since I am more familiar with that.

 

Sub GetTransformParameters()
    
    Dim oDoc As AssemblyDocument
    Set oDoc = ThisApplication.ActiveDocument
    
    Dim oDef As AssemblyComponentDefinition
    Set oDef = oDoc.ComponentDefinition

    'Select UCS from Part
    Dim oUCS_From As UserCoordinateSystem
    Set oUCS_From = ThisApplication.CommandManager.Pick(kUserCoordinateSystemFilter, "Select Sensor (""From"") UCS")
    
    'Select USC from Assembly - Currently there is only 1 and its Named: UCS_Reference
    Dim oUCS_To As UserCoordinateSystem
    Set oUCS_To = oDef.UserCoordinateSystems.Item(1)
    
    'Get the PartComponentDefinition in order to get the transformation necessary to create a matrix
    Dim occDef As ComponentDefinition
    Set occDef = oUCS_From.Parent
    
    Dim occ As ComponentOccurrence
    Dim occMatrix As Matrix
    
    For Each occ In oDef.Occurrences
        If occ.Definition Is occDef Then
            Set occMatrix = occ.Transformation
        End If
    Next
        
    Dim oMatrix_From As Matrix
    Set oMatrix_From = oUCS_From.Transformation
    'Call oMatrix_From.TransformBy(occMatrix) ' Commented out from uncertainty
    
    Dim oMatrix_To As Matrix
    Set oMatrix_To = oUCS_To.Transformation
    Call oMatrix_To.TransformBy(occMatrix)
    
    
    Dim oOrigin1 As Point
    Dim oXAxis1 As Vector
    Dim oYAxis1 As Vector
    Dim oZAxis1 As Vector
    ' Get the CS as origin point and axis vectors for oMatrix1
    Call oMatrix_From.GetCoordinateSystem(oOrigin1, oXAxis1, oYAxis1, oZAxis1)
    
    Dim oOrigin2 As Point
    Dim oXAxis2 As Vector
    Dim oYAxis2 As Vector
    Dim oZAxis2 As Vector
    ' Get the CS as origin point and axis vectors for oMatrix2
    Call oMatrix_To.GetCoordinateSystem(oOrigin2, oXAxis2, oYAxis2, oZAxis2)
    
    Dim oMatrix As Matrix
    ' Create new 4X4 Matrix object and initialize as identity
    Set oMatrix = ThisApplication.TransientGeometry.CreateMatrix
    ' Set oMatrix to transform "from" oUCS_From "to" oUCS_To
    Call oMatrix.SetToAlignCoordinateSystems(oOrigin1, oXAxis1, oYAxis1, oZAxis1, oOrigin2, oXAxis2, oYAxis2, oZAxis2)



' NEW CODE HERE

' Get document units
Dim oUOM As UnitsOfMeasure
Set oUOM = oDoc.UnitsOfMeasure

' Get conversion factor
Dim oConvFactor As Double
oConvFactor = oUOM.ConvertUnits(1, UnitsTypeEnum.kDatabaseLengthUnits, oUOM.LengthUnits)

' Convert Matrix to array
Dim oMatrixArray(15) As Double
Call oMatrix.GetMatrixData(oMatrixArray)

For i = 0 To 12
' Convert translation values of 4th row of matrix from centimeters to document units
If Len(CStr((i + 1) / 4)) = 1 Then oMatrixArray(i) = oMatrixArray(i) * oConvFactor
' Round all array values to set number of decimal places
oMatrixArray(i) = Round(oMatrixArray(i), 5)
Next

' Format string for MessageBox to display as a matrix
For Row = 0 To 3
MsgStr = MsgStr & vbLf
For Col = 0 To 3
MsgStr = MsgStr & vbTab & oMatrixArray(Row * 4 + Col)
Next
Next

Call MsgBox(MsgStr)

End Sub

 

0 Likes
Message 3 of 4

gilsdorf_e
Collaborator
Collaborator

I had a similiar problem some weeks ago. It seems like UCS transformation methods only support the translation part. I ended up transforming the matrices myself.

0 Likes
Message 4 of 4

lukas.juette
Observer
Observer

 

 

0 Likes