Extracting the Angles of An Occurrence and using them to place a new copy of it
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello,
I have tried reading all posts relating to extracting the angles iproperties from an occurrence and then using them to transform a new matrix that is then used to place another copy of the same occurrence grounded in the exact same position.
Extracting the angles seem to work first with this code:
Modified to use within ilogic:
Imports System
Imports System.Math
Sub Main()
Dim oDoc As AssemblyDocument
oDoc = ThisDoc.Document
Dim oOcc As ComponentOccurrence
Dim oOc_Name As String
Dim Map As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap()
If RuleArguments.Exists("Component_Name") Then
oOc_Name = RuleArguments("Component_Name")
MessageBox.Show(oOc_Name)
Else
oOc_Name = "Counter - 1.ipt:1"
End If
oOcc = oDoc.ComponentDefinition.Occurrences.ItemByName(oOc_Name)
Dim oMat As Matrix
oMat = oOcc.Transformation
Dim aRotAngles(2) As Double
Call CalculateRotationAngles(oMat, aRotAngles)
Dim Numbers_Store As New ArrayList
Dim i As Integer
For i = 0 To 2
MessageBox.Show(FormatNumber(aRotAngles(i), 5))
Numbers_Store.Add(FormatNumber(aRotAngles(i), 5))
Next i
SharedVariable("Angles") = Numbers_Store
End Sub
Sub CalculateRotationAngles(ByVal oMatrix As Inventor.Matrix, ByRef aRotAngles() As Double)
'Const PI = 3.14159265358979
'Const TODEGREES As Double = 180 / PI
Dim dB As Double
Dim dC As Double
Dim dNumer As Double
Dim dDenom As Double
Dim dAcosValue As Double
Dim oRotate As Inventor.Matrix
Dim oAxis As Inventor.Vector
Dim oCenter As Inventor.Point
oRotate = ThisApplication.TransientGeometry.CreateMatrix
oAxis = ThisApplication.TransientGeometry.CreateVector
oCenter = ThisApplication.TransientGeometry.CreatePoint
oCenter.X = 0
oCenter.Y = 0
oCenter.Z = 0
' Choose aRotAngles[0] about x which transforms axes[2] onto the x-z plane
dB = oMatrix.Cell(2, 3)
dC = oMatrix.Cell(3, 3)
dNumer = dC
dDenom = Sqrt(dB * dB + dC * dC)
' Make sure we can do the division. If not, then axes[2] is already in the x-z plane
If (Abs(dDenom) <= 0.000001) Then
aRotAngles(0) = 0#
Else
If (dNumer / dDenom >= 1#) Then
dAcosValue = 0#
Else
If (dNumer / dDenom <= -1#) Then
dAcosValue = PI
Else
dAcosValue = Acos(dNumer / dDenom)
End If
End If
aRotAngles(0) = Sign(dB) * dAcosValue
oAxis.X = 1
oAxis.Y = 0
oAxis.Z = 0
Call oRotate.SetToRotation(aRotAngles(0), oAxis, oCenter)
Call oMatrix.PreMultiplyBy(oRotate)
End If
' Choose aRotAngles[1] about y which transforms axes[3] onto the z axis
If (oMatrix.Cell(3, 3) >= 1#) Then
dAcosValue = 0#
Else
If (oMatrix.Cell(3, 3) <= -1#) Then
dAcosValue = PI
Else
dAcosValue = Acos(oMatrix.Cell(3, 3))
End If
End If
aRotAngles(1) = Math.Sign(-oMatrix.Cell(1, 3)) * dAcosValue
oAxis.X = 0
oAxis.Y = 1
oAxis.Z = 0
Call oRotate.SetToRotation(aRotAngles(1), oAxis, oCenter)
Call oMatrix.PreMultiplyBy(oRotate)
' Choose aRotAngles[2] about z which transforms axes[0] onto the x axis
If (oMatrix.Cell(1, 1) >= 1#) Then
dAcosValue = 0#
Else
If (oMatrix.Cell(1, 1) <= -1#) Then
dAcosValue = PI
Else
dAcosValue = Acos(oMatrix.Cell(1, 1))
End If
End If
aRotAngles(2) = Math.Sign(-oMatrix.Cell(2, 1)) * dAcosValue
aRotAngles(0) = aRotAngles(0)
aRotAngles(1) = aRotAngles(1)
aRotAngles(2) = aRotAngles(2)
End Sub
Public Function Acos(value) As Double
Acos = Math.Atan(-value / Math.Sqrt(-value * value + 1)) + 2 * Math.Atan(1)
End Function
The Angles are then exported as shared variable back to the rule where the iteration is occurring and the matrix transformation are occurring:
Dim oAsmDoc As AssemblyDocument oAsmDoc = ThisDoc.Document Dim oAsmDef As AssemblyComponentDefinition oAsmDef = oAsmDoc.ComponentDefinition Dim iLogicAuto As Object iLogicAuto = iLogicVb.Automation Dim oOcc As ComponentOccurrence Dim Occurrences As ComponentOccurrences Dim X_Int As Double Dim Y_Int As Double Dim Z_Int As Double Dim oTG As TransientGeometry oTG = ThisApplication.TransientGeometry Dim oMatrix As Matrix oMatrix = oTG.CreateMatrix Dim oTempMatrix_1 As Matrix Dim oTempMatrix_2 As Matrix Dim oTempMatrix_3 As Matrix Dim oTempMatrix_4 As Matrix Dim oTempMatrix_5 As Matrix Dim oTempMatrix_6 As Matrix Dim oMatrix_1 As Matrix oTempMatrix_1 = oTG.CreateMatrix oTempMatrix_2 = oTG.CreateMatrix oTempMatrix_3 = oTG.CreateMatrix oTempMatrix_4 = oTG.CreateMatrix oTempMatrix_5 = oTG.CreateMatrix oTempMatrix_6 = oTG.CreateMatrix Dim Location As String Dim oPart As PartDocument Dim oPart_Def As PartComponentDefinition Dim Part_Location As String Dim Part_Name As String Dim New_Assembly_Name As String Dim Map As Inventor.NameValueMap = ThisApplication.TransientObjects.CreateNameValueMap() Dim Angles_Group As New ArrayList Dim HDPE_Components As New ArrayList HDPE_Components.Add("Driving Mounting Panel.ipt") HDPE_Components.Add("Steering Wheel.ipt") HDPE_Components.Add("Wave Bridge Plastic Panel.ipt") HDPE_Components.Add("Sun Panel.ipt") HDPE_Components.Add("Counter.ipt") 'HDPE_Components.Add("Flower Infill Panel.ipt") For Each oOcc In oAsmDef.Occurrences 'On Error Resume Next If HDPE_Components.Contains(iProperties.Value(oOcc.Name, "Custom", "PFN")) AndAlso oOcc.DefinitionDocumentType = kPartDocumentObject Then X_Int = FormatNumber(oOcc.Transformation.Translation.X, 2, vbTrue, vbFalse, vbFalse) Y_Int = FormatNumber(oOcc.Transformation.Translation.Y, 2, vbTrue, vbFalse, vbFalse) Z_Int = FormatNumber(oOcc.Transformation.Translation.Z, 2, vbTrue, vbFalse, vbFalse) oPart = oOcc.ReferencedDocumentDescriptor.ReferencedDocument Part_Location = oPart.FullDocumentName Part_Location = Left(Part_Location, InStrRev(Part_Location, "\")) Part_Name = Right(oPart.FullDocumentName, Len(oPart.FullDocumentName) -Len(Part_Location)) Part_Name = Left(Part_Name, Len(Part_Name) - 4) New_Assembly_Name = Part_Location + Part_Name + ".iam" 'MessageBox.Show(New_Assembly_Name) 'iLogicAuto.RunExternalRule(oPart, "Update Component") 'iLogicAuto.RunExternalRule(oPart, "HDPE Part to Assembly") Map.Add("Component_Name", oOcc.Name) iLogicAuto.RunExternalRuleWithArguments(oAsmDoc, "Extract Angles", Map) Map.Clear Call oMatrix.SetTranslation(oTG.CreateVector(X_Int, Y_Int, Z_Int)) oOcc = oAsmDef.Occurrences.Add(New_Assembly_Name, oMatrix) oMatrix_1 = oOcc.Transformation If SharedVariable.Exists("Angles") Then Angles_Group = SharedVariable("Angles") MessageBox.Show(Angles_Group(0) & vbCr & Angles_Group(1) & vbCr & Angles_Group(2), "All Angles") Call oTempMatrix_1.SetToRotation(Angles_Group(0), oTG.CreateVector(1, 0, 0), oTG.CreatePoint(X_Int, Y_Int, Z_Int)) Call oTempMatrix_1.SetToRotation(Angles_Group(1), oTG.CreateVector(0, 1, 0), oTG.CreatePoint(X_Int, Y_Int, Z_Int)) Call oTempMatrix_3.SetToRotation(Angles_Group(2), oTG.CreateVector(0, 0, 1), oTG.CreatePoint(X_Int, Y_Int, Z_Int)) Call oTempMatrix_4.TransformBy(oTempMatrix_1) Call oTempMatrix_5.TransformBy(oTempMatrix_4) Call oTempMatrix_6.TransformBy(oTempMatrix_5) Call oMatrix_1.TransformBy(oTempMatrix_6) oOcc.Transformation = oMatrix_1 SharedVariable.Remove("Angles") End If 'oOcc.Visible = False 'oOcc.Grounded = True 'oOcc.ComponentDefinition.Update End If Next 'iLogicVb.RunExternalRule("Browser Rename") iLogicVb.UpdateWhenDone = True
i think i have two errors:
1. the 180 deg is being read as 0.0 radians
2. the matrix transform by method is not correct, as in I need to check all 3 angles so i need to set to rotation at each angle, then transform by each consecutively?
Thanks In advance.