Creating an Absolute Datum CSYS for mirroring a body

Hi there,
I could do with a little bit of help regarding the creation of an absolute Datum CSYS. The recording of course uses the exact origin coordinates of the specific case. But hopefully there is a general way create a datum CSYS which always represents the absolute origin.

As for the context Im working inside a component of an assembly where a body needs to be mirrored along the absolute y-plane. For now this is done by the user selecting the plane from csys that has to be created before. If however there is a way to select the absolute y-plane directly I'm also interessted in this, cause maybe I could drop the user input part that way.

Thank you so much in advance!

The yet almost unedited code for Datum CSYS creation so far looks like this:

' NX 9.0.2.5
'
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.View

Module NXJournal
Sub Main (ByVal args() As String)

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work

Dim displayPart As Part = theSession.Parts.Display

' ----------------------------------------------
' Menu: Insert->Datum/Point->Datum CSYS...
' ----------------------------------------------
Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Start")

Dim nullFeatures_Feature As Features.Feature = Nothing

If Not workPart.Preferences.Modeling.GetHistoryMode Then
Throw(New Exception("Create or edit of a Feature was recorded in History Mode but playback is in History-Free Mode."))
End If

Dim datumCsysBuilder1 As Features.DatumCsysBuilder
datumCsysBuilder1 = workPart.Features.CreateDatumCsysBuilder(nullFeatures_Feature)

theSession.SetUndoMarkName(markId1, "Datum CSYS Dialog")

Dim xform1 As Xform
xform1 = workPart.Xforms.CreateXform(SmartObject.UpdateOption.WithinModeling, 1.0)

xform1.RemoveParameters()

Dim origin1 As Point3d = New Point3d(-557.713135211474, 729.669412952803, -521.585999999966)
xform1.SetOrigin(origin1)

Dim markId2 As Session.UndoMarkId
markId2 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Datum CSYS")

theSession.DeleteUndoMark(markId2, Nothing)

Dim markId3 As Session.UndoMarkId
markId3 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Datum CSYS")

Dim cartesianCoordinateSystem1 As CartesianCoordinateSystem
cartesianCoordinateSystem1 = workPart.CoordinateSystems.CreateCoordinateSystem(xform1, SmartObject.UpdateOption.WithinModeling)

theSession.DeleteUndoMark(markId3, Nothing)

theSession.SetUndoMarkName(markId1, "Datum CSYS")

datumCsysBuilder1.Csys = cartesianCoordinateSystem1

datumCsysBuilder1.DisplayScaleFactor = 1.0

Dim nXObject1 As NXObject
nXObject1 = datumCsysBuilder1.Commit()

datumCsysBuilder1.Destroy()

theSession.CleanUpFacetedFacesAndEdges()

' ----------------------------------------------
' Menu: Tools->Journal->Stop Recording
' ----------------------------------------------

End Sub
End Module

And the main code for the mirroring operation like this:

' NX 9.0.2.5
'
Option Strict Off
Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports System.IO

Module NXJournal
Sub Main (ByVal args() As String)

Dim theSession As Session = Session.GetSession()
Dim workPart As Part = theSession.Parts.Work

Dim displayPart As Part = theSession.Parts.Display

Dim markId1 As Session.UndoMarkId
markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Start")

Dim nullFeatures_Feature As Features.Feature = Nothing

If Not workPart.Preferences.Modeling.GetHistoryMode Then
Throw(New Exception("Create or edit of a Feature was recorded in History Mode but playback is in History-Free Mode."))
End If

'Dim origin1 As Point3d = New Point3d(0.0, 0.0, 0.0)
'Dim normal1 As Vector3d = New Vector3d(0.0, 1.0, 0.0)
Dim Mirrorplane As DatumPlane
SelectAPlane("select mirrorplane", Mirrorplane)

' ----------------------------------------------
' Menu: Insert->Associative Copy->Extract Geometry...
' ----------------------------------------------
Dim markId4 As Session.UndoMarkId
markId4 = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Start")

Dim wavePointBuilder1 As Features.WavePointBuilder
wavePointBuilder1 = workPart.Features.CreateWavePointBuilder(nullFeatures_Feature)

Dim waveDatumBuilder1 As Features.WaveDatumBuilder
waveDatumBuilder1 = workPart.Features.CreateWaveDatumBuilder(nullFeatures_Feature)

Dim compositeCurveBuilder1 As Features.CompositeCurveBuilder
compositeCurveBuilder1 = workPart.Features.CreateCompositeCurveBuilder(nullFeatures_Feature)

Dim extractFaceBuilder1 As Features.ExtractFaceBuilder
extractFaceBuilder1 = workPart.Features.CreateExtractFaceBuilder(nullFeatures_Feature)

Dim mirrorBodyBuilder1 As Features.MirrorBodyBuilder
mirrorBodyBuilder1 = workPart.Features.CreateMirrorBodyBuilder(nullFeatures_Feature)

compositeCurveBuilder1.Tolerance = 0.001

extractFaceBuilder1.FaceOption = Features.ExtractFaceBuilder.FaceOptionType.FaceChain

compositeCurveBuilder1.FixAtCurrentTimestamp = True

waveDatumBuilder1.ParentPart = Features.WaveDatumBuilder.ParentPartType.WorkPart

wavePointBuilder1.ParentPart = Features.WavePointBuilder.ParentPartType.WorkPart

extractFaceBuilder1.ParentPart = Features.ExtractFaceBuilder.ParentPartType.WorkPart

mirrorBodyBuilder1.ParentPartType = Features.MirrorBodyBuilder.ParentPart.WorkPart

compositeCurveBuilder1.ParentPart = Features.CompositeCurveBuilder.PartType.WorkPart

theSession.SetUndoMarkName(markId4, "Extract Geometry Dialog")

compositeCurveBuilder1.Section.DistanceTolerance = 0.001

compositeCurveBuilder1.Section.ChainingTolerance = 0.00095

mirrorBodyBuilder1.Associative = True

mirrorBodyBuilder1.FixAtCurrentTimestamp = True

mirrorBodyBuilder1.InheritDisplayProperties = False

mirrorBodyBuilder1.CopyThreads = False

Dim features1(0) As Features.Feature
Dim extractFace1 As Features.ExtractFace = CType(workPart.Features.FindObject("LINKED_FACE(0)"), Features.ExtractFace)

features1(0) = extractFace1
Dim component1 As Assemblies.Component = CType(displayPart.ComponentAssembly.RootComponent.FindObject("COMPONENT 2014-10-20_MODEL 1"), Assemblies.Component)

Dim bodyFeatureRule1 As BodyFeatureRule
bodyFeatureRule1 = workPart.ScRuleFactory.CreateRuleBodyFeature(features1, True, component1)

Dim rules1(0) As SelectionIntentRule
rules1(0) = bodyFeatureRule1
mirrorBodyBuilder1.MirrorBodyCollector.ReplaceRules(rules1, False)

mirrorBodyBuilder1.Plane.Value = Mirrorplane

Dim markId5 As Session.UndoMarkId
markId5 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Extract Geometry")

theSession.DeleteUndoMark(markId5, Nothing)

Dim markId6 As Session.UndoMarkId
markId6 = theSession.SetUndoMark(Session.MarkVisibility.Invisible, "Extract Geometry")

Dim nXObject1 As NXObject
nXObject1 = mirrorBodyBuilder1.Commit()

theSession.DeleteUndoMark(markId6, Nothing)

theSession.SetUndoMarkName(markId4, "Extract Geometry")

compositeCurveBuilder1.Destroy()

waveDatumBuilder1.Destroy()

wavePointBuilder1.Destroy()

extractFaceBuilder1.Destroy()

mirrorBodyBuilder1.Destroy()

theSession.CleanUpFacetedFacesAndEdges()

' ----------------------------------------------
' Menu: Tools->Journal->Stop Recording
' ----------------------------------------------

End Sub
Function SelectAPlane(ByVal prompt As String, ByRef selObj As DatumPlane) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim title As String = "Select the global Y plane as mirrorplane"
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_datum_plane_type
.Subtype = UFConstants.UF_datum_object_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
End Module

If you want to create a datum csys at the absolute origin, use the code you have, but change the origin coordiates in line 39 to be (0,0,0).

If the part already has a datum csys located at absolute (as the default part template files do), you will be able to use this existing plane rather than create a new one.

Below is code that will find the YZ plane of the datum csys at absolute (if there is one).

'NXJournaling.com
'October 27, 2014
'
'Test the datum Csys features in the work part, find the YZ plane
'of the datum csys at absolute.

Option Strict Off
Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF

Module find_absolute_YZ

Dim theSession As Session = Session.GetSession()
Dim theUfSession As UFSession = UFSession.GetUFSession
Dim workPart As Part = theSession.Parts.Work
Dim lw As ListingWindow = theSession.ListingWindow

Sub Main()

If IsNothing(theSession.Parts.Work) Then
'active part required
Return
End If

lw.Open()

Dim myYzPlane As DatumPlane 'YZ plane of datum csys
Dim planeFound As Boolean = False

For Each myFeature As Features.Feature In workPart.Features

'skip features other than DatumCsys
If Not TypeOf (myFeature) Is Features.DatumCsys Then
Continue For
End If

If IsDatumCsysAtAbsolute(myFeature) Then
'do something
myYzPlane = DatumCsysYzPlane(myFeature)
planeFound = True

'stop looking
Exit For

End If

Next

If planeFound Then
lw.WriteLine("Absolute YZ datum plane found")
lw.WriteLine("Plane normal direction: " & myYzPlane.Normal.ToString)
myYzPlane.Highlight()
Else
lw.WriteLine("Absolute YZ datum plane NOT found")
End If

lw.Close()

End Sub

Function IsDatumCsysAtAbsolute(ByVal theDatumCsys As Features.DatumCsys) As Boolean

Dim csys_tag As Tag
Dim origin_tag As Tag
Dim daxes As Tag()
Dim dplanes As Tag()
theUfSession.Modl.AskDatumCsysComponents(theDatumCsys.Tag, csys_tag, origin_tag, daxes, dplanes)

Dim datumOrigin As Point = Utilities.NXObjectManager.Get(origin_tag)
Dim absoluteOrigin As New Point3d(0, 0, 0)

Dim Xaxis As DatumAxis = Utilities.NXObjectManager.Get(daxes(0))
Dim absoluteXVector As New Vector3d(1, 0, 0)

Dim Yaxis As DatumAxis = Utilities.NXObjectManager.Get(daxes(1))
Dim absoluteYVector As New Vector3d(0, 1, 0)

If datumOrigin.Coordinates.Equals(absoluteOrigin) Then
If Not Xaxis.Direction.Equals(absoluteXVector) Then
Return False
End If

If Not Yaxis.Direction.Equals(absoluteYVector) Then
Return False
End If

Return True
Else
Return False
End If

End Function

Function DatumCsysYzPlane(ByVal theDatumCsys As Features.DatumCsys) As DatumPlane

lw.WriteLine(theDatumCsys.GetFeatureName)

Dim csys_tag As Tag
Dim origin_tag As Tag
Dim daxes As Tag()
Dim dplanes As Tag()
theUfSession.Modl.AskDatumCsysComponents(theDatumCsys.Tag, csys_tag, origin_tag, daxes, dplanes)

Dim YZPlane As DatumPlane = Utilities.NXObjectManager.Get(dplanes(1))

Return YZPlane

End Function

Public Function GetUnloadOption(ByVal dummy As String) As Integer

'Unloads the image when the NX session terminates
GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination

'----Other unload options-------
'Unloads the image immediately after execution within NX
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

'Unloads the image explicitly, via an unload dialog
'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Explicitly
'-------------------------------

End Function

End Module

Thanks for your reply.
The code is working great. As for the absolute origin (0,0,0) of course does the job for the components origin, but if the component is moved the nx command to create an Absolute CSYS uses the assemblies absolute origin which the code doesn't. But I've found a solution for that aswell. If someone is interessted in this it works by asking for the components position [component1.GetPosition()] first and reversing these coordinates.