Examine Geometry

Examine your geometry

Make Euclid proud

Even if you are a brand new user to NX, you should be familiar with the Examine Geometry command, it can be found in the Analysis menu. Running this check will ensure your model is valid during the modeling process and for downstream uses (drafting, FEA, CAM, etc). At a minimum, the model should be required to pass the face and body checks before releasing the file for production; also, running examine geometry is the recommended first step in troubleshooting should your file develop strange behavior (boolean operation failing, mass properties obviously incorrect, section view strangeness, shaded views missing faces, etc, etc). If you are unfamiliar with the command or just want more background, search the GTAC solution center with the phrase "examine geometry" to find several informative articles. There are links to three of the articles below, you will need a webkey to access the GTAC site.

Unigraphics - Examine and check geometry

NX - Understanding and utilizing the examine geometry function

NX - Repairing errors found using the Examine Geometry function

Divide and Conquer

When you have a parameterized file that does not pass the geometry checks, it can become a tedious task to hunt down the offending geometry. When I starting using NX, I was taught a "divide and conquer" technique to help quickly identify the problem entities. The goal is to identify which feature in the history tree is causing the model to fail the checks. We put "bounds" around the bad feature and through a series of tests we can progressively narrow the bounds until we find the offending feature. The overall steps are as follows:

  1. The first feature is the lower bound (feature A), the last feature in the history tree is the upper bound (feature B).
  2. Unsuppress all features, fix any/all feature errors.
  3. Run examine geometry with all body and face checks set (at a minimum).
  4. Set the current feature in the tree to the point 1/2 way between the upper and lower bound, re-run the examine geometry checks.
    1. If the check fails, we know the error is somewhere between the lower bound (feature A) and the current feature. Make note of the current feature number, this becomes the new upper bound (feature B).
    2. If the check passes, we know the error is somewhere between the current feature and the upper bound (feature B). Make note of the current feature number, this becomes the new lower bound (feature A).
  5. Go to step 4 and repeat until you find the offending feature

The list above looks very much like an algorithm because, well... it is an algorithm. If you have studied numerical methods, you may recognize it bears a strong resemblance to the bisection root finding method.

Now that we have an algorithm, let's put it to use:

[vbnet]'NXJournaling.com
'January 9, 2013
'tested on NX 8
'journal version 0.11 (beta release)
' 0.11: fixed bug where journal would crash if "cancel" was clicked in the selection step

'Journal runs geometry checks (body structure, body consistency, face-face intersect, face self-intersect)
'on the selected solid. You do not need to window select the geometry (as you do with the examine geometry command),
'the journal will automatically select the faces of the selected solid body.

'If the solid does not pass one of the initial checks, the journal will search for the last feature in the history tree
'where the target solid passed all the checks. This feature will be made the current feature.

'** Note: This does not necessarily mean that the next feature is causing the failure, but should serve as
' a good starting point in your search for the bad geometry.
' For example: suppose you have a file with 1000 features and the journal indicates feature 882 is the
' last valid state of the solid; this does not necessarily mean that SUBTRACT(883) is the problem.
' Perhaps the real problem is the geometry in THROUGH_CURVE_MESH(876) that trims the tool body of SUBTRACT(883).
' In this case, the journal simply indicates that the geometry that contributes to SUBTRACT(883) needs to be investigated.

'Usage notes:
' The journal will prompt for the selection of a solid body.
' If the body passes all the checks, a note indicating success will be written to the Information Window
' If the body fails a check, the journal will search for the last feature in the history tree where the selected body
' passed all the checks.
' The journal works best on parts that are fully parameterized and have no suppressed features or features with errors.
' There is no point of running this journal on a solid body that is a "body" feature (imported body), the examine geometry
' will serve better in this case.

'I don't consider this the 'final' version of this journal; there are other options and checks I'd like to add.
'Any suggestions, bug reports, or general feedback can be sent to info@nxjournaling.com
'Thanks!

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

Module examine_geometry

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

Sub Main()

lw.Open()

Dim myFeatures As Features.Feature() = workPart.Features.GetFeatures

Dim featureCount As Integer = 0
Dim featureA As Integer = 0
Dim featureB As Integer = 0
Dim featureX As Integer = 0
Dim featureCheck As Features.Feature

Dim featureList As New List(Of Features.Feature)

For Each someFeature As Features.Feature In myFeatures

If Not (someFeature.IsInternal Or someFeature.Suppressed) Then
featureList.Add(someFeature)
End If

Next

featureCount = featureList.Count
'lw.WriteLine("Feature count: " & featureCount.ToString)
featureB = featureCount - 1

Dim mySolid As Body

If SelectSolid("Select a solid body", mySolid) = Selection.Response.Cancel Then
Exit Sub
End If

Dim partGood As Boolean = False
partGood = GoodGeometry(mySolid)

If Not partGood Then
lw.WriteLine("Current feature: " & workPart.CurrentFeature.GetFeatureName)
lw.WriteLine("Failed geometry check")
Do Until (featureB - featureA) <= 1
featureX = featureA + (featureB - featureA) \ 2
lw.WriteLine("")
featureCheck = featureList.Item(featureX)
featureCheck.MakeCurrentFeature()
lw.WriteLine("Current feature: " & workPart.CurrentFeature.GetFeatureName)
partGood = GoodGeometry(mySolid)
If partGood Then
featureA = featureX
Else
featureB = featureX
End If
Loop

lw.WriteLine("")
lw.WriteLine("Current feature adjusted to last good state of selected solid")

Else
lw.WriteLine("Passed all geometry checks")
End If

End Sub

Function GoodGeometry(ByVal someSolid As Body) As Boolean

Dim myFaces() As Face = someSolid.GetFaces

Dim badFacesEdges As Integer
Dim faultTags(-1) As Tag
Dim faultTokens(-1) As Integer
Dim faceSelfIntersectPoint(2) As Double
ufs.Modl.AskBodyStructures(someSolid.Tag, badFacesEdges, faultTags)
If badFacesEdges = 0 Then
lw.WriteLine("Passed Body Structure test")
ufs.Modl.AskBodyConsistency(someSolid.Tag, badFacesEdges, faultTokens, faultTags)
If badFacesEdges = 0 Then
lw.WriteLine("Passed Body Consistency test")
ufs.Modl.AskFaceFaceIntersect(someSolid.Tag, badFacesEdges, faultTags)
If badFacesEdges = 0 Then
lw.WriteLine("Passed Face Face Intersect test")
For Each faceToTest As Face In myFaces
ufs.Modl.AskFaceSelfIntersect(faceToTest.Tag, badFacesEdges, faceSelfIntersectPoint)
If badFacesEdges = 0 Then
'lw.WriteLine("Face passed self-intersection test")
Else
lw.WriteLine("Failed Face self intersection test")
Exit For
Return False
End If
Next
lw.WriteLine("Passed Face self intersection test")
Return True
Else
lw.WriteLine("Failed Face Face Intersect test")
Return False
End If
Else
lw.WriteLine("Failed Body Consistency test")
Return False
End If
Else
lw.WriteLine("Failed Body Structure test")
Return False
End If

lw.Close()

End Function

Function SelectSolid(ByVal prompt As String, ByRef selObj As NXObject) As Selection.Response

Dim theUI As UI = UI.GetUI
Dim title As String = "Select a solid body"
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.WorkPart
Dim selectionMask_array(0) As Selection.MaskTriple

With selectionMask_array(0)
.Type = UFConstants.UF_solid_type
.SolidBodySubtype = UFConstants.UF_UI_SEL_FEATURE_SOLID_BODY
End With

Dim resp As Selection.Response = theUI.SelectionManager.SelectObject(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

Public Function GetUnloadOption(ByVal dummy As String) As Integer

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

End Function

End Module[/vbnet]

Usage notes

This journal is meant to be run on a fully parameterized model since it will search for the "last good feature". If you need to check unparameterized bodies, I'd suggest running the interactive Examine Geometry checks. If you only have one feature in the file (the unparameterized body feature) and it fails the checks, the journal may crash or do other strange things (I don't know exactly what it will do since I don't currently have such a file to check against).

Normally when you use the examine geometry command, you will window select around the solid body so that the body, all the faces, and all the edges get selected. The journal will prompt you to select a solid body, it will collect all the faces and edges it needs from this single selection. The journal will write messages to the information window as it runs to keep you informed as to what is happening. It currently only runs the body structure, body consistency, face face intersection, and face self intersection tests. If the solid of interest passes all of these checks, congratulations! you are done. If the solid does not pass one or more of the checks, the journal will run through the steps outlined above. The model will be left with the current feature set to the last one where the model passes all the checks. Check out the parent geometry for the next feature in the tree, chances are good it is causing the problem.

Programming notes

If you record a journal when using the examine geometry function, the code you will get will look very different from my code. There is an ExamineGeometry object that allows you to set the checks to run, run the checks, etc, etc. However, as of this writing, there is a bug with the GetResults method that causes the journal to crash. When this bug is fixed in a future update, I'd like to revisit this code and clean it up to use the .NET versions of the various functions.

Conclusion

This article is a good example of translating a process used in interactive NX, translating it to an algorithm, and finally implementing that algorithm into code. I hope it has resulted in a time-saving journal that you will find useful.

So, what manual processes are you following in NX? It's time to automate them!