Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations cowski on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

Journal Moving Component Csys to Csys 1

Status
Not open for further replies.

DHuskic

Computer
Dec 18, 2012
114
I am attempting to move a component from a csys I created on its solid body to the ABS csys to try and keep it simple(if I can do this then will I simply translate the component later). The problem is rotating the component correctly. The solid body is not consistent with the component csys. I have both csys' created and have tried numerous code samples, as well as trying to combine some of those and using combinations of the group. Any help is greatly appreciated as I have ran out of ideas to try.

DHuskic
Data Prep Nx 7.5 & Nx 8.5
Kettering University Class of '17
 
Replies continue below

Recommended for you

You should have a look at the API called "Sample Open C API program : reposition selected component" in the GTAC library - does not seem far from what you want to do here.
I'd say "UF_ASSEM_reposition_part_occurrence" is a good start to investigate...
 
The code works great for moving components. I've developed an algorithm for its use on components when the component-csys is aligned with the solid body. In my case, I need to use a csys on a solid body(let's call this the MoveFromCsys) within the component that is not in line with the absolute csys. I have tried feeding in the MoveFromCsys position and orientation into those type of functions without success(it executes but does not do what I want). Debugging those matrices is difficult because I can't find the matrix definition or explanation anywhere.

I've used this thread[CompRot], to learn about component rotations. Then, using Gtac examples, perform transform operations to get the component csys back on top of the absolute csys. I was to use the same algorithms for this, but I need to figure out how to feed the MoveFromCsys information into one of those examples.

DHuskic
Data Prep Nx 7.5 & Nx 8.5
Kettering University Class of '17
 
Hello DHuskic, can You provide the code with everything You have done now?

With best regards
Michael
 
I'm using the AskTranslation and AskRotation calls to break this matrix up, but then my results are still confusing. I found this and have been trying to use it as a guideline.
Code:
'Attempt to use mtx4Transform
                    Dim translation(2) As Double
                    TheUfSession.Mtx4.AskTranslation(mtx4Transform, translation)
                    Dim rotation(8) As Double
                    TheUfSession.Mtx4.AskRotation(mtx4Transform, rotation)
                    TheUfSession.Mtx3.Transpose(rotation, rotation)
Then I attempt to feed translation and rotation into either of these examples with unexpected results. I'll keep plugging away at it but if you know better code to move components with, that would help.
RepositionIntstance
DragByTransform

Thank you for all your help.

DHuskic
Data Prep Nx 7.5 & Nx 8.5
Kettering University Class of '17
 
Try the code below; it assumes the "from" csys belongs to the component that you want to move and the "to" csys belongs to the assembly. The code was tested in NX 8.5 to move a top level component (one owned directly by the assembly, not one nested 2 or more levels deep).

Code:
'NXJournaling.com
'January 5, 2015
'Move a component from Csys to Csys
'Journal will prompt user to select a "from" csys and a "to" csys; the "from" csys should belong to the
'component that you want to move.

Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module1

    Sub Main()

        Dim theSession As Session = Session.GetSession()
        Dim theUfSession As UFSession = UFSession.GetUFSession()
        If IsNothing(theSession.Parts.Work) Then
            'active part required
            Return
        End If

        Dim workPart As Part = theSession.Parts.Work
        Dim lw As ListingWindow = theSession.ListingWindow
        lw.Open()

        Const undoMarkName As String = "reposition component"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

        Dim fromCsys As CoordinateSystem
        Dim toCsys As CoordinateSystem

        If SelectCsys("Select 'From' coordinate system", fromCsys) = Selection.Response.Cancel Then
            Return
        End If

        If SelectCsys("Select 'To' coordinate system", toCsys) = Selection.Response.Cancel Then
            Return
        End If

        'calculate Csys to Csys transformation matrix
        Dim fromOrigin() As Double = {fromCsys.Origin.X, fromCsys.Origin.Y, fromCsys.Origin.Z}
        Dim fromXAxis() As Double = {fromCsys.Orientation.Element.Xx, fromCsys.Orientation.Element.Xy, fromCsys.Orientation.Element.Xz}
        Dim fromYAxis() As Double = {fromCsys.Orientation.Element.Yx, fromCsys.Orientation.Element.Yy, fromCsys.Orientation.Element.Yz}

        Dim toOrigin() As Double = {toCsys.Origin.X, toCsys.Origin.Y, toCsys.Origin.Z}
        Dim toXAxis() As Double = {toCsys.Orientation.Element.Xx, toCsys.Orientation.Element.Xy, toCsys.Orientation.Element.Xz}
        Dim toYAxis() As Double = {toCsys.Orientation.Element.Yx, toCsys.Orientation.Element.Yy, toCsys.Orientation.Element.Yz}

        Dim mtx4Transform(15) As Double

        theUfSession.Mtx4.CsysToCsys(fromOrigin, fromXAxis, fromYAxis, toOrigin, toXAxis, toYAxis, mtx4Transform)

        'extract the rotation matrix and the tranlsation vector
        Dim rotMatrix(8) As Double
        theUfSession.Mtx4.AskRotation(mtx4Transform, rotMatrix)
        Dim transVec(2) As Double
        theUfSession.Mtx4.AskTranslation(mtx4Transform, transVec)

        'convert array of doubles to vector 3d
        Dim translateVector As Vector3d = New Vector3d(transVec(0), transVec(1), transVec(2))
        'convert array of doubles to Matrix3x3
        Dim rotationMatrix As Matrix3x3 = convertToMatrix3x3(rotMatrix)

        'determine component to move based on the chosen "from" csys
        Dim comp As Assemblies.Component = fromCsys.OwningComponent
        Dim componentPositioner1 As Positioning.ComponentPositioner = theSession.Parts.Work.ComponentAssembly.Positioner

        Dim network1 As Positioning.Network
        network1 = componentPositioner1.EstablishNetwork()

        Dim componentNetwork1 As Positioning.ComponentNetwork = CType(network1, Positioning.ComponentNetwork)
        Dim markId2 As Session.UndoMarkId = Nothing

        If comp IsNot Nothing Then
            markId2 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Move Component")

            Dim movableObjects() As NXObject = {comp}
            componentNetwork1.SetMovingGroup(movableObjects)
            'reposition component from the rotation matrix and translation vector
            componentNetwork1.DragByTransform(translateVector, rotationMatrix)
            componentNetwork1.Solve()

        End If

        theSession.UpdateManager.AddToDeleteList(componentNetwork1)
        theSession.UpdateManager.DoUpdate(markId2)

        lw.Close()

    End Sub

    Function SelectCsys(ByVal prompt As String, ByRef selObj As TaggedObject) As Selection.Response

        Dim theUI As UI = UI.GetUI
        Dim title As String = "Select a Coordinate system"
        Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim cursor As Point3d
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
        Dim selectionMask_array(0) As Selection.MaskTriple

        With selectionMask_array(0)
            .Type = UFConstants.UF_coordinate_system_type
            .Subtype = UFConstants.UF_all_subtype
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selobj, cursor)
        If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If

    End Function

    Function convertToMatrix3x3(ByVal mtx As Double()) As Matrix3x3

        Dim mx As Matrix3x3
        With mx
            .Xx = mtx(0)
            .Xy = mtx(1)
            .Xz = mtx(2)
            .Yx = mtx(3)
            .Yy = mtx(4)
            .Yz = mtx(5)
            .Zx = mtx(6)
            .Zy = mtx(7)
            .Zz = mtx(8)
        End With

        Return mx

    End Function

End Module


www.nxjournaling.com
 
Thank you Cowski for the help. The program works, it moves the components correctly but I cannot get them to stick. I attempted to save all and reopen but the components moved back to their previous condition. I started changing some of the componentPositioner fields/methods but I can't the components to stay. As soon as I modify something with the component it resets back to it's previous position. I am also confused with the calls the markId's perform, if you could elaborate on the function of these?

DHuskic
Data Prep Nx 7.5 & Nx 8.5
Kettering University Class of '17
 
DHuskic said:
The program works, it moves the components correctly but I cannot get them to stick.

Whoops! I was so focused on getting the component to move correctly that I forgot to "apply" the move. The corrected code is below:

Code:
'NXJournaling.com
'January 5, 2015
'Move a component from Csys to Csys
'Journal will prompt user to select a "from" csys and a "to" csys; the "from" csys should belong to the
'component that you want to move.


Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module1

    Sub Main()

        Dim theSession As Session = Session.GetSession()
        Dim theUfSession As UFSession = UFSession.GetUFSession()
        If IsNothing(theSession.Parts.Work) Then
            'active part required
            Return
        End If

        Dim workPart As Part = theSession.Parts.Work
        Dim lw As ListingWindow = theSession.ListingWindow
        lw.Open()

        Const undoMarkName As String = "reposition component"
        Dim markId1 As Session.UndoMarkId
        markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)

        Dim fromCsys As CoordinateSystem
        Dim toCsys As CoordinateSystem

        If SelectCsys("Select 'From' coordinate system", fromCsys) = Selection.Response.Cancel Then
            Return
        End If

        If SelectCsys("Select 'To' coordinate system", toCsys) = Selection.Response.Cancel Then
            Return
        End If

        'calculate Csys to Csys transformation matrix
        Dim fromOrigin() As Double = {fromCsys.Origin.X, fromCsys.Origin.Y, fromCsys.Origin.Z}
        Dim fromXAxis() As Double = {fromCsys.Orientation.Element.Xx, fromCsys.Orientation.Element.Xy, fromCsys.Orientation.Element.Xz}
        Dim fromYAxis() As Double = {fromCsys.Orientation.Element.Yx, fromCsys.Orientation.Element.Yy, fromCsys.Orientation.Element.Yz}

        Dim toOrigin() As Double = {toCsys.Origin.X, toCsys.Origin.Y, toCsys.Origin.Z}
        Dim toXAxis() As Double = {toCsys.Orientation.Element.Xx, toCsys.Orientation.Element.Xy, toCsys.Orientation.Element.Xz}
        Dim toYAxis() As Double = {toCsys.Orientation.Element.Yx, toCsys.Orientation.Element.Yy, toCsys.Orientation.Element.Yz}

        Dim mtx4Transform(15) As Double

        theUfSession.Mtx4.CsysToCsys(fromOrigin, fromXAxis, fromYAxis, toOrigin, toXAxis, toYAxis, mtx4Transform)

        'extract the rotation matrix and the tranlsation vector
        Dim rotMatrix(8) As Double
        theUfSession.Mtx4.AskRotation(mtx4Transform, rotMatrix)
        Dim transVec(2) As Double
        theUfSession.Mtx4.AskTranslation(mtx4Transform, transVec)

        'convert array of doubles to vector 3d
        Dim translateVector As Vector3d = New Vector3d(transVec(0), transVec(1), transVec(2))
        'convert array of doubles to Matrix3x3
        Dim rotationMatrix As Matrix3x3 = convertToMatrix3x3(rotMatrix)

        'determine component to move based on the chosen "from" csys
        Dim comp As Assemblies.Component = fromCsys.OwningComponent
        Dim componentPositioner1 As Positioning.ComponentPositioner = theSession.Parts.Work.ComponentAssembly.Positioner

        Dim network1 As Positioning.Network
        network1 = componentPositioner1.EstablishNetwork()

        Dim componentNetwork1 As Positioning.ComponentNetwork = CType(network1, Positioning.ComponentNetwork)
        Dim markId2 As Session.UndoMarkId = Nothing

        If comp IsNot Nothing Then
            markId2 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Move Component")

            Dim movableObjects() As NXObject = {comp}
            componentNetwork1.SetMovingGroup(movableObjects)
            componentNetwork1.BeginDrag()
            'reposition component from the rotation matrix and translation vector
            componentNetwork1.DragByTransform(translateVector, rotationMatrix)
            componentNetwork1.EndDrag()
            componentNetwork1.ResetDisplay()
            componentNetwork1.ApplyToModel()

            componentNetwork1.Solve()

        End If

        theSession.UpdateManager.AddToDeleteList(componentNetwork1)
        theSession.UpdateManager.DoUpdate(markId2)

        lw.Close()

    End Sub

    Function SelectCsys(ByVal prompt As String, ByRef selObj As TaggedObject) As Selection.Response

        Dim theUI As UI = UI.GetUI
        Dim title As String = "Select a Coordinate system"
        Dim includeFeatures As Boolean = False
        Dim keepHighlighted As Boolean = False
        Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
        Dim cursor As Point3d
        Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
        Dim selectionMask_array(0) As Selection.MaskTriple

        With selectionMask_array(0)
            .Type = UFConstants.UF_coordinate_system_type
            .Subtype = UFConstants.UF_all_subtype
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObject(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selobj, cursor)
        If resp = Selection.Response.ObjectSelected OrElse resp = Selection.Response.ObjectSelectedByName Then
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If

    End Function

    Function convertToMatrix3x3(ByVal mtx As Double()) As Matrix3x3

        Dim mx As Matrix3x3
        With mx
            .Xx = mtx(0)
            .Xy = mtx(1)
            .Xz = mtx(2)
            .Yx = mtx(3)
            .Yy = mtx(4)
            .Yz = mtx(5)
            .Zx = mtx(6)
            .Zy = mtx(7)
            .Zz = mtx(8)
        End With

        Return mx

    End Function

End Module


markId1 and markId2 are undo marks. markId1 exists only so that the user can "undo" the results of the journal; it is for convenience and can be omitted if desired. The DoUpdate method requires an undo mark as an argument; if any errors occur during the update, NX will roll back to the given undo mark and throw an exception. In this short example journal, markId1 could have been used instead of making a new mark to use. A longer, "real world" program might have many steps which you would not want to undo should an update error occur. In this case, I'd suggest creating an undo mark for each significant step so as to not roll back all the way to the start of the journal.

www.nxjournaling.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor