Selecting a face in Python

Forums: 

Hello all,

I'm translating my VB codes into Python because I can't find a method to return the results of Python data bank back to VB codes.

1.
While I translated the selection function into Python by AI, it generated two additional lines:
from NXOpen import UFSession, UFConstants
from NXOpen.UF import MaskTriple, Selection

If I already have import NXOpen and import NXOpen.UF above, do I still need the two lines?

2.
I have import NXOpen.Utilities above, but somehow NX said there is ImportError: NXOpen.Utilities at the boolean keepHighlighted.
How can I solve the problem?

3.
This example in the link initializes variables with the syntax, which is a little bit similar to VB:
uf_obj: NXOpen.UF.Obj = theUfSession.Obj
(There is already import NXOpen.UF above.)

When do we use this kind of syntax, instead of uf_obj = theUfSession.Obj?
https://www.cnblogs.com/hustmse0510/p/15662332.html


import NXOpen
import NXOpen.UF
import NXOpen.Features
import NXOpen.Utilities
from NXOpen.Utilities import Snap

theSession = NXOpen.Session.GetSession()
workPart = theSession.Parts.Work
theUI = NXOpen.UI.GetUI() # not sure
theUfSession = UFSession.GetUFSession()
lw = theSession.ListingWindow
dispObj1 = None
minPt = None

def main():
lw.Open()

if theSession.Parts.Work is None:
lw.WriteLine("No work part for processing")
return

partBodiesArray = list(workPart.Bodies)
theBody = None
myMeasure = theSession.Parts.Display.MeasureManager()
displayPart = theSession.Parts.Display
dispObj1 = SelectFace()

if dispObj1 is None:
# Face selection canceled
return

minPt = PointOnSelectedFace(dispObj1)

# Achtung: partBodiesArray() speichert verschiedene Koerpers

# Pruefen den Flaechentypen
lw.WriteLine(dispObj1.SolidFaceType.ToString())
lw.WriteLine("Number of BODIES in part= " + str(len(partBodiesArray)))

theBody = dispObj1.GetBody()
for theBody in partBodiesArray:
attributes = theBody.GetUserAttributes()
# Lese Materialtypen aus (Read material types)
for attribute in attributes:
# Equivalent of lw.WriteLine(attribute.Title & " = " & attribute.StringValue) in Python
lw.WriteLine(f"{attribute.Title} = {attribute.StringValue}")

bodyDensity = theBody.Density() # kilograms per cubic meter, 1 kg / (m3) = 1.0 * 10-6 g / (mm3)

lw.Close()

if __name__ == "__main__":
main()

from NXOpen import UFSession, UFConstants
from NXOpen.UF import MaskTriple, Selection
def select_face():
dispObj1 = None

# Variablen fuer Auswahl-Dialoge (Selection Dialogs)
selManager = theUI.SelectionManager
selectedObject = None
cursor = Point3d(0.0, 0.0, 0.0) # Replace with the desired starting point
cue = "Bitte waehle die Flaeche, auf der gelasert wird, aus."
title = "Kosten- und CO2-Rechner"
scope = Selection.SelectionScope.WorkPart
action = Selection.SelectionAction.ClearAndEnableSpecific
includeFeatures = False
keepHighlighted = False
faceMask = MaskTriple(UFConstants.UF_face_type, 0, 0)
maskArray = [faceMask]
response = selManager.SelectTaggedObject(cue, title, scope, action, includeFeatures, keepHighlighted, maskArray,
selectedObject, cursor)

if response == Selection.Response.ObjectSelected or response == Selection.Response.ObjectSelectedByName:
if isinstance(selectedObject, NXOpen.Face):
dispObj1 = selectedObject

return dispObj1

1. I think the added lines are not necessary and actually incorrect as written. "Selection" should be imported from NXOpen, not NXOpen.UF. Likewise, "UFConstants" should be imported from NXOpen.UF instead of NXOpen. You can shorten up some lines of code with these imports, but they are not required.

2. I don't think the Utilities import is needed.

3. This style of declaring variables is called "type hinting". This is optional in python; the interpreter ignores it, but can be useful in the IDE or with 3rd party tools (code checkers and linters).
https://docs.python.org/3.8/library/typing.html

The code below will allow you to select a face and report the density of the solid body that owns the face.

import NXOpen
import NXOpen.UF
import NXOpen.Features
from NXOpen import Selection
from NXOpen.UF import UFConstants

theSession = NXOpen.Session.GetSession()
workPart = theSession.Parts.Work
theUI = NXOpen.UI.GetUI()
theUfSession = NXOpen.UF.UFSession.GetUFSession()
lw = theSession.ListingWindow
dispObj1 = None
minPt = None

def select_face():
dispObj1 = None

# Variablen fuer Auswahl-Dialoge (Selection Dialogs)
cue = "Bitte waehle die Flaeche, auf der gelasert wird, aus."
title = "Kosten- und CO2-Rechner"
scope = Selection.SelectionScope.WorkPart
action = Selection.SelectionAction.ClearAndEnableSpecific
includeFeatures = False
keepHighlighted = False
maskArray = [None] * 1
maskArray[0] = Selection.MaskTriple(UFConstants.UF_face_type, 0, 0)
response, selObj1, cursor1 = theUI.SelectionManager.SelectTaggedObject(cue, title, scope, action, includeFeatures, keepHighlighted, maskArray)

if response == Selection.Response.ObjectSelected or response == Selection.Response.ObjectSelectedByName:
if isinstance(selObj1, NXOpen.Face):
dispObj1 = selObj1
return dispObj1

def main():
lw.Open()

if theSession.Parts.Work is None:
lw.WriteLine("No work part for processing")
return

partBodiesArray = list(workPart.Bodies)
theBody = None
myMeasure = theSession.Parts.Display.MeasureManager
displayPart = theSession.Parts.Display
dispObj1 = select_face()

if dispObj1 is None:
# Face selection canceled
return

#minPt = PointOnSelectedFace(dispObj1)

# Achtung: partBodiesArray() speichert verschiedene Koerpers

# Pruefen den Flaechentypen
lw.WriteLine(str(dispObj1.SolidFaceType))
lw.WriteLine("Number of BODIES in part= " + str(len(partBodiesArray)))

theBody = dispObj1.GetBody()
# for theBody in partBodiesArray:
# attributes = theBody.GetUserAttributes()
# # Lese Materialtypen aus (Read material types)
# for attribute in attributes:
# # Equivalent of lw.WriteLine(attribute.Title & " = " & attribute.StringValue) in Python
# lw.WriteLine(f"{attribute.Title} = {attribute.StringValue}")

bodyDensity = theBody.Density # kilograms per cubic meter, 1 kg / (m3) = 1.0 * 10-6 g / (mm3)
lw.WriteLine('density: ' + str(bodyDensity))

lw.Close()

if __name__ == "__main__":
main()

Hello NXJournaling,

Thanks for your help, and it works fine now!

Although I found that SNAP doesn't support Python, and I have to work on pythonnet and the original VB codes now, I'm curious about this:
Since I have import NXOpen.UF above, I thought I don't need to mention NXOpen.UF explicit.
I looked the references up, but found no details...
https://docs.plm.automation.siemens.com/data_services/resources/nx/1899/...
https://docs.plm.automation.siemens.com/data_services/resources/nx/10/nx...

How to know when to add NXOpen.UF like the code below?
theUfSession = NXOpen.UF.UFSession.GetUFSession()

"Since I have import NXOpen.UF above, I thought I don't need to mention NXOpen.UF explicit."

We probably could have shortened a few more lines in that code. My general process is: try it out, if it doesn't work - adjust the import statement or fully qualify the reference.

I would use the SelectObjects function instead of SelectTaggedObject.

import NXOpen
import NXOpen.UF
import NXOpen.Features

theSession = NXOpen.Session.GetSession()
workPart = theSession.Parts.Work
theUI = NXOpen.UI.GetUI()
theLw = theSession.ListingWindow

theLw.Open()

def main():

if theSession.Parts.Work is None:
lw.WriteLine("No work part for processing")
return

thefaces={}
thefaces = select_faces()

if len(thefaces) == 0:
# Face selection canceled
return

theLw.WriteLine("len = "+str(len(thefaces)))
theLw.WriteLine("thefaces = "+str(thefaces))
theLw.WriteLine("thefaces.SolidFaceType = "+str(thefaces[0].SolidFaceType))
theLw.WriteLine("thefaces.Tag = "+str(thefaces[0].Tag))
theBody1 = thefaces[0].GetBody()
theLw.WriteLine("theBody1.Density = "+str(theBody1.Density))

def select_faces():

message = "Select Faces"
title = "Selection"
scope = NXOpen.SelectionSelectionScope.WorkPart
keepHighlighted = False

typeArray = [NXOpen.SelectionSelectionType.Faces]

selTuple = theUI.SelectionManager.SelectObjects(message, title, scope, keepHighlighted, typeArray)

if selTuple[0] == NXOpen.SelectionResponse.ObjectSelected:
theLw.WriteLine(" selTuple[0]" + str(selTuple[0]))

return selTuple[1]

if __name__ == '__main__':
main()

"I would use the SelectObjects function instead of SelectTaggedObject."

I would not recommend this as the "SelectObject" and "SelectObjects" functions have been deprecated for several releases now (since NX 8). The recommended functions are "SelectTaggedObject" and "SelectTaggedObjects".