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 :
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