Get Owning Component of User Selected Datum CSYS (Within Assembly)

I'd post the code but it's 630 lines long. In essence, I have the user select a datum CSYS that they want to convert from the context of the assembly to the context of the work part's default datum CSYS (to avoid association issues). I have coded all of the wavelink functionality but I have one roadblock.

In order to gain the correct CSYS information, I need to use the following line

toCsys = component1.FindOccurrence(toCsys)

Where "toCsys" is a cartesianCoordinateSystem that is apart of a Datum CSYS that the user selected, and component1 is the owning component of the Datum CSYS.

The problem is I do not know how to define component1 based off the the selected Datum CSYS, display part, or the work part. I've researched several posts on how prototypes, components, and FindOccurrence works, but I don't understand it well enough to extract the owning component of the Datum CSYS.

Most attempts I've tried is met with the following error:

"System.NullReferenceException: Object reference not set to an instance of an object."

Note: The datum CSYS the user selects is from "AnyInAssembly" scope. Meaning that the owning part of the datum CSYS will not be the current workpart. I'm not sure what other information I need to provide.

If I'm understanding this correctly, the user has an assembly open with a certain component set as the current work part and they are selecting a csys object from a different component in the assembly. If this is the case, chances are very good that the csys they have selected is an occurrence. In this case component1 = toCsys.OwningComponent.

If the csys chosen is a prototype, it was likely selected from the current work part. Based on the description, it sounds like you would want to prevent selection of a prototype csys (one that belongs to the current work part). If I remember correctly, "any in assembly" would allow you to select something from the current workpart or any other component in the assembly. I don't think we can automatically assume that the chosen csys is NOT from the current work part (unless you have other code that disallows such a selection).

The .FindOccurrence method only works when you pass in a prototype object.
csysOcc = comp1.FindOccurrence(csysProto)
I'd suggest adding a line to check if the selected csys is an occurrence or not and taking appropriate action.
if chosenCsys.IsOccurrence then...

You are understanding the correctly, the datum of the component should be of a different work part from active work part.


If SelectDatum("Select datum feature to reference", toDatumCsys) = Selection.Response.Cancel Then
Return
End If

Dim toCsysClass As New NXJ_DatumCsys
toCsysClass.TheDatumCsys = toDatumCsys
toCsys = toCsysClass.Csys

If toDatumCsys.OwningPart.Equals(workPart) Then
If Replacement("Reselect reference datum to replace", OBJ) = Selection.Response.Cancel Then
Copy = true
End If
Else
Dim component1 As NXOpen.Assemblies.Component = Nothing
If Component("Select Component", component1) = Selection.Response.Cancel Then
Return
End If

If toCsys.IsOccurrence = false Then
Copy = true
Name = component1.Name
toCsys = component1.FindOccurrence(toCsys)

lw.WriteLine(Name)
lw.Writeline(toCsys.OwningComponent.Name)
Return
End If

Is my code for trying to debug the situation with toCsys and component1 The functions for "SelectDatum" and "Component" are user selection functions as shown below


Function SelectDatum(ByVal prompt As String, ByRef selObj As TaggedObject) As Selection.Response
Dim theUI As UI = UI.GetUI
Dim title As String = "Select the Parent Datum Feature"
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_feature_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 Component(ByVal prompt As String, ByRef selObj As TaggedObject) As Selection.Response
Dim theUI As UI = UI.GetUI
Dim title As String = "Select the Parent Part of CSYS"
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_component_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

My misunderstanding comes from the If statement:
If toDatumCsys.OwningPart.Equals(workPart) Then

This is to detect if the datumcsys to be selected is the same as the current workpart, of which my code is to skip the wavelink process entirely. The above statement returns false, which pushes the user to select the owning component of the datum csys and move on with the code. The function below is sourced from my previous forum post: http://www.nxjournaling.com/content/extracting-coordinate-system-type-da...


Dim toCsysClass As New NXJ_DatumCsys
toCsysClass.TheDatumCsys = toDatumCsys
toCsys = toCsysClass.Csys

If snippets won't help solve the issue, I'll clean up my code, comment out the problem points, and upload it to the forum.

The main issue is that you really shouldn't try to access feature information for features outside of the current work part. Instead of selecting a datum csys feature, I'd suggest selecting a coordinate system object directly.

Sub Main()

Dim theSession As Session = Session.GetSession()
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()

Dim toDatumCsys As CoordinateSystem = Nothing
If SelectCsys("Select coordinate system to reference", toDatumCsys) = Selection.Response.Cancel Then
Return
End If

'Dim toCsysClass As New NXJ_DatumCsys
'toCsysClass.TheDatumCsys = toDatumCsys
'Dim toCsys As CoordinateSystem = Nothing
'toCsys = toCsysClass.Csys

If toDatumCsys.OwningPart.Equals(workPart) Then
lw.WriteLine("owning part == work part")
Else
lw.WriteLine("owning part != work part")
Dim component1 As NXOpen.Assemblies.Component = Nothing
component1 = toDatumCsys.OwningComponent
lw.WriteLine("owning component: " & component1.DisplayName)
End If

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 the 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_csys_normal_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