How to get the Coordinate of a centroid point

Hi there ! First question here. I'm trying to develop APIs for my team. The one that I work on is a making this :

1) The user select parts in an assembly ;
2) Each constraints of each part is removed ;
3) Each part get a Fixed constraint .

It works. But I also want to place the ConstraintReference.HelpPoint . Tho archive this I loop in the part to find bodies and try to average a centroid from them. The problem is :

I have my average centroid Point3d but it is not a coordinate from the CSYS of the parent part. For exemple : centroid of PART1 is (0,0,5) and PART1 is at (50,10,20) in ASSEMBLY1. what I get is an HelpPoint at (0,0,5) but what I need is an HelpPoint at (50,10,25).

I'm looking on the internet for a while without finding my answer. I hope someone can guide me.

Here is my entire script, the centroid part start with the Fonction GetCenter() :

Imports System
Imports System.Globalization
Imports System.Text.RegularExpressions
Imports System.IO
'Imports System.Collections

Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies
Imports NXOpen.UI
Imports NXOpen.Utilities
Imports NXOpen.Positioning

Module FixSelectedObj
Public theSession As Session = Session.GetSession()
Public ufs As UFSession = UFSession.GetUFSession()

Sub Main()

Dim markId1 As NXOpen.Session.UndoMarkId = theSession.SetUndoMark(NXOpen.Session.MarkVisibility.Invisible, "Fixer Composants")
Dim MyNXClass As New MyClassNXOpen
MyNXClass.Echo("--------------- START AT " & Date.Now.ToLongTimeString & " ---------------")

Dim workPart As Part = theSession.Parts.Work
Dim displayPart As Part = theSession.Parts.Display
Dim lw As ListingWindow = theSession.ListingWindow
Dim mySelectedObjects As New List(Of DisplayableObject)
Dim theUI As UI = UI.GetUI()

Try
Dim CompList As TaggedObject()

CompList = SelectListObjects("Sélectionnez des pièces ")

If IsNothing(CompList) Then
MyNXClass.Echo("Tâche annulée, aucune pièce sélectionnée")
Else
For Each item As NXObject In CompList
'MyNXClass.Echo(item.JournalIdentifier)
MyNXClass.Echo("Pièce : " & item.GetStringUserAttribute("DB_PART_DESC", -1))
'MyNXClass.Echo("Pièce parent : " & item.OwningComponent.GetStringUserAttribute("DB_PART_DESC", -1))
DeleteConstraint(item)
FixComponent(item)
Next
End If
Catch ex As Exception
MyNXClass.Echo("Failed: " & ex.ToString)
End Try

MyNXClass.Echo("--------------- FINISH AT " & Date.Now.ToLongTimeString & " ---------------")
theSession.DeleteUndoMark(markId1, Nothing)
MyNXClass.GetUnloadOption()

End Sub

Function SelectListObjects(prompt As String) As TaggedObject()

Dim MyClassNX As New MyClassNXOpen

Dim selObj As TaggedObject() = Nothing
Dim theUI As UI = UI.GetUI
Dim title As String = "Select objects"
Dim includeFeatures As Boolean = False
Dim keepHighlighted As Boolean = False
Dim selAction As Selection.SelectionAction = Selection.SelectionAction.ClearAndEnableSpecific
Dim scope As Selection.SelectionScope = Selection.SelectionScope.AnyInAssembly
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = NXOpen.UF.UFConstants.UF_component_type
.SolidBodySubtype = NXOpen.UF.UFConstants.UF_component_subtype
End With

Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, title, scope, selAction, includeFeatures, keepHighlighted, selectionMask_array, selObj)

If resp = Selection.Response.ObjectSelected Or resp = Selection.Response.ObjectSelectedByName Or resp = Selection.Response.Ok Then
Return selObj
Else
Return Nothing
End If

End Function

Sub DeleteConstraint(ByVal CompDel As Component)
'.
Dim MyNXClass As New MyClassNXOpen
Dim parentPart As Part = CType(CompDel.Parent.Prototype, Part)
Dim workPart As Part = CType(CompDel.Prototype, Part)
Dim msg As NXMessageBox = UI.GetUI().NXMessageBox
Dim tmpName As String

Try
Dim save_arrangement = parentPart.ComponentAssembly.ActiveArrangement

Dim marque As Session.UndoMarkId = theSession.SetUndoMark(Session.MarkVisibility.Visible, "Delete Constraints")

For Each a As Arrangement In parentPart.ComponentAssembly.Arrangements

parentPart.ComponentAssembly.ActiveArrangement = a
Dim RegworkPartID As New Regex(workPart.JournalIdentifier.ToString, RegexOptions.IgnoreCase)

For Each c As ComponentConstraint In parentPart.ComponentAssembly.Positioner.Constraints
tmpName = c.Name.ToString
If RegworkPartID.IsMatch(tmpName) Then
theSession.UpdateManager.AddToDeleteList(c)
Else
End If
Next
theSession.UpdateManager.DoAssemblyConstraintsUpdate(marque)

Next
parentPart.ComponentAssembly.ActiveArrangement = save_arrangement
MyNXClass.Echo("Toutes les contraintes du composant sont supprimées")

Catch ex As Exception
MyNXClass.Echo("Failed at Del : " & ex.ToString)
End Try

ufs.Modl.Update()

End Sub

Sub FixComponent(ByVal CompFix As Component)

Dim MyNXClass As New MyClassNXOpen
Dim tmpParent As Component = CompFix.Parent
Dim workPart As Part = theSession.Parts.FindObject(tmpParent.DisplayName)

Try
Dim CP As Positioning.ComponentPositioner = workPart.ComponentAssembly.Positioner
CP.ClearNetwork()

Dim activ_arrangement = workPart.ComponentAssembly.ActiveArrangement
Dim arrangement1 As Assemblies.Arrangement = CType(activ_arrangement, Assemblies.Arrangement)
CP.PrimaryArrangement = arrangement1
CP.BeginAssemblyConstraints()

Dim allowInterpartPositioning1 As Boolean
allowInterpartPositioning1 = theSession.Preferences.Assemblies.InterpartPositioning

theSession.Preferences.Assemblies.InterpartPositioning = True

Dim Network As Positioning.Network
Network = CP.EstablishNetwork()

Dim CN As Positioning.ComponentNetwork = CType(Network, Positioning.ComponentNetwork)
CN.DisplayComponent = Nothing
CN.NetworkArrangementsMode = Positioning.ComponentNetwork.ArrangementsMode.Existing
CN.MoveObjectsState = True

'*** Fix
Dim Constraint1 As Positioning.Constraint = CP.CreateConstraint()

Dim CConstraint1 As Positioning.ComponentConstraint = CType(Constraint1, Positioning.ComponentConstraint)
CConstraint1.ConstraintType = Positioning.Constraint.Type.Fix

Dim ConstraintRef1 As Positioning.ConstraintReference = CConstraint1.CreateConstraintReference(CompFix, CompFix, False, False, False)

Dim helpPoint1 As NXOpen.Point3d
helpPoint1 = GetCenter(CompFix)
ConstraintRef1.HelpPoint = helpPoint1

CN.Solve()
CN.ApplyToModel()

CP.ClearNetwork()
CP.DeleteNonPersistentConstraints()
CP.EndAssemblyConstraints()

MyNXClass.Echo("Le composant est fixé !")
Catch ex As Exception
MyNXClass.Echo("Failed at Fix : " & ex.ToString)
End Try

End Sub

Function GetCenter(ByVal CompCenter As Component) As Point3d

Dim MyNXClass As New MyClassNXOpen
Dim nb As Integer = 0
Dim tmpX As Integer = 0
Dim tmpY As Integer = 0
Dim tmpZ As Integer = 0
Dim tmpPart As Part = theSession.Parts.FindObject(CompCenter.Name)
Dim tmpcomp As Component = CompCenter
Dim tmpchild As Part
Dim CG As NXOpen.Point3d = New Point3d(tmpX, tmpY, tmpZ)

Try
For Each body In tmpPart.Bodies
nb = nb + 1
Next body

If nb > 0 Then

For Each body In tmpPart.Bodies
Dim theBodies(0) As Body
theBodies(0) = body
Dim myMeasure As MeasureManager = theSession.Parts.Display.MeasureManager()
Dim massUnits(1) As Unit
massUnits(0) = theSession.Parts.Display.UnitCollection.GetBase("Volume")

Dim mb As MeasureBodies = Nothing
'***.NewMassProperties(array of units, accuracy parameter, array of bodies to measure)
mb = myMeasure.NewMassProperties(massUnits, 0.99, theBodies)
mb.InformationUnit = MeasureBodies.AnalysisUnit.GramMillimeter

CG = mb.Centroid
tmpX = tmpX + mb.Centroid.X
tmpY = tmpY + mb.Centroid.Y
tmpZ = tmpZ + mb.Centroid.Z

Next
tmpX = tmpX / nb
tmpY = tmpY / nb
tmpZ = tmpZ / nb
CG = New Point3d(tmpX, tmpY, tmpZ)

Else

If tmpcomp.GetChildren.Length <> 0 Then
For Each child In tmpcomp.GetChildren()
tmpchild = theSession.Parts.FindObject(child.Name)
nb = 0
For Each body In tmpchild.Bodies
nb = nb + 1
Next

If nb > 0 Then

For Each body In tmpchild.Bodies
Dim theBodies(0) As Body
theBodies(0) = body
Dim myMeasure As MeasureManager = theSession.Parts.Display.MeasureManager()
Dim massUnits(1) As Unit
massUnits(0) = theSession.Parts.Display.UnitCollection.GetBase("Volume")

Dim mb As MeasureBodies = Nothing
'***.NewMassProperties(array of units, accuracy parameter, array of bodies to measure)
mb = myMeasure.NewMassProperties(massUnits, 0.99, theBodies)
mb.InformationUnit = MeasureBodies.AnalysisUnit.GramMillimeter

CG = mb.Centroid
tmpX = tmpX + mb.Centroid.X
tmpY = tmpY + mb.Centroid.Y
tmpZ = tmpZ + mb.Centroid.Z

Next body
tmpX = tmpX / nb
tmpY = tmpY / nb
tmpZ = tmpZ / nb
CG = New Point3d(tmpX, tmpY, tmpZ)

Else
'CG = New Point3d(0, 0, 0)
End If
Next child
Else
'CG = New Point3d(0, 0, 0)
End If
End If
Catch ex As Exception
MyNXClass.Echo("Failed at GetCenter : " & ex.ToString)
'CG = New Point3d(0, 0, 0)
End Try
Return CG

End Function

Public Function GetUnloadOption() 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

Little Update :

I ended up using the seach function in NXOpen API refecence .htm and fund an answer :

Using the NameLocation of my component (it seems to use the CSYS of the component to get the coordinate) ...

So here is what I add in my code :

tmpX = tmpX / nb + CompCenter.NameLocation.X
tmpY = tmpY / nb + CompCenter.NameLocation.Y
tmpZ = tmpZ / nb + CompCenter.NameLocation.Z
CG = New Point3d(tmpX, tmpY, tmpZ)

Sorry