Showing results for 
Search instead for 
Do you mean 

Minimum Face radius - Random sense


I'm trying to use GeometricAnalysis.geometric properties to get the minimum radius of a face at a given point.

I was expecting the sign of the radius output by invofminradiusofcurvature to be dependant on the face normal however if I reverse the face normal and check again there is no change in sign.

I've also tried the Local Radius Analysis tool in the UI and this behaves in the same way.  The sign of the radius output appears to be random.

As such I can't distinguish between concave or convex faces on a solid.

My aim is to be able to find the location of the minimum radius of a face and know whether it is concave or convex.

Is there a better function to use than I'm trying, or am I misunderstanding the output of the functions I've been using so far?


As always thanks in advance for any help offered.


Re: Minimum Face radius - Random sense

Interestingly in NX10 Localradiusanalysisbuilder updates the sign of the output radii when you flip face normals.

However... I can't see a way of getting the radii out of the builder.  It appears to only display the values on the screen.

The GeometricAnalysis.GeometricProperties.Face tool doesn't change it's sign when the face normal is reversed but can output the values. Smiley Sad

Even so my production environment is NX8.5. Smiley Frustrated

Re: Minimum Face radius - Random sense

[ Edited ]

In the immortal words of Hannibal Lechter ...

First principles, Clarice. Simplicity. Read Marcus Aurelius. Of each and every particular thing ask: what is it in and of itself? What is its nature?


If you can't find another way, then you can compute curvature from first principles. For code to compute Gaussian curvature, you can look here:


New info: the function NXOpen.UF.UFModl.AskFaceProps looks promising. I don't know how it handles surface normal flipping and sign chnages, though. If you find out, I'd be very interested to know.




Re: Minimum Face radius - Random sense

[ Edited ]

I played around with NXOpen.UF.UFModl.AskFaceProps, and it seems to work the way I would expect. It returns the principal radii at the given point on the surface. These are the reciprocals of the principal curvatures. You can look up principal curvatures in any book on differential geometry, and there are descriptions in the NX docs (look up "Gaussian curvature").


The radius values returned are positive when the surface is concave (viewed from outside) and negative when the surface is convex. Here "outside" means the region of air (as opposed to the region consisting of material).


So, if you're looking for regions where a milling cutter would gouge the surface, look for places where one of the radius values returned is positive and smaller than the cutter radius.


Now that I've figured this out, I'll probably add a function to SNAP, so that it's available and understandable the next time I need it.


Re: Minimum Face radius - Random sense



Thanks for your help on this.  I've been off on another project for the last few days, so only just got back to looking at this today.

The AskFaceProps function looks really useful.

I'm finding that the sign of the face appears to be linked to the normal of the face (although only tested this with 2 faces on a sheet body).

I also like the fact that it will return the point on the face from u,v location, as this is somehting I was having to do with scalars and nxopen points before.  This is going to be a big efficiency improvement.


The one issue I am having is with particular surfaces though.

face blend surfaces produced with constant radius are tending to produce the following exception:

"NXOpen.NXException: Modeler error. Initiating error recovery."


using evaluate face fails on the same faces with the following exception:

"NXOpen.NXException: NX error status: 825018"



Would there be a reason why these functions would be tripped up by faces with constant curvature in a single direction?




Re: Minimum Face radius - Random sense

The sign of the curvature is indeed related to the surface normal.


It's a bit complicated, but here goes:


The face has a "natural" normal, N1, which is just the cross product of the partial derivatives. Then there is an "outward" normal, N2, which points away from material. So N2 = sense*N1, where sense is +1 or -1.


This function returns the outward normal.


So, suppose you locate yourself out in the "air", some distance along the outward normal, and stare at the surface. If the surface looks concave to you, then the curvature(s) will be positive, and if the the surface looks convex, the curvatures will be negative. Of course, the surface could be saddle-shaped (concave in some directions and convex in others), in which case the two curvatures will have opposite signs.


For example, on the cylindrical surface of a 20mm diameter hole, the principal radii are (10, infinity). Similarly, on the cylindrical surface of a 10mm diameter boss, the principal radii are (-5, infinity


Regarding the Exception you mentioned ..  I haven't seen that in my testing, and I have tried constant-radius blends.




Re: Minimum Face radius - Random sense

Here's my test code. It uses SNAP's brand new face.Curvatures method, but you can substitute the NXOpen function, instead:



Option Infer On
Imports Snap, Snap.Create, Snap.NX.ObjectTypes

Module NXJournal

   Sub Main()

      For Each body In Snap.Globals.WorkPart.Bodies
         For Each face In body.Faces
            Dim faceType As String = face.ObjectSubType.ToString
            InfoWindow.WriteLine("Face: " & faceType)

            Dim nU = 5
            Dim nV = 5
            Dim box As Snap.Geom.Box2d = face.BoxUV
            Dim minU = box.MinU : Dim maxU = box.MaxU : Dim stepU = (maxU - minU) / nU
            Dim minV = box.MinV : Dim maxV = box.MaxV : Dim stepV = (maxV - minV) / nV

            For u = minU To maxU + 0.001 Step stepU
               For v = minV To maxV + 0.001 Step stepV
                  Dim k = face.Curvatures(u,v)
                  Dim k0 = k(0).ToString("F4")
                  Dim k1 = k(1).ToString("F4")
                  InfoWindow.WriteLine(k0 & " ; " & k1)
               Next v
            Next u

         Next face
      Next body

   End Sub

End Module




Re: Minimum Face radius - Random sense

Try with the file attached.

1 blend was created as a face blend const rad.  The others were edge blends o na solid.

All 3 blends fail to output face properties with the exceptions above (on NX8.5).

I've not tested nx10 yet.

Re: Minimum Face radius - Random sense

The test code I posted works for me (in NX10) with your part file.


The only odd thing I noticed is that you have several b-surfaces that are actually planar.


What's the message from the exception you're getting?


Re: Minimum Face radius - Random sense

I created the part as a cube.  Then extracted the faces (bsurf) to create the freeform regions and then applied a sew after.  Hence b surf geometry in there.


I've not had a chance to test your code however here is my test code and this consistently fails on the test part I sent you in both NX8.5 & NX10


Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF

Module Module1
    Dim theSession As Session = Session.GetSession()
    Dim theUfSession As UFSession = UFSession.GetUFSession()
    Public workpart As Part = theSession.Parts.Work
    '  Explicit Activation
    '      This entry point is used to activate the application explicitly
    Sub Main()

        Dim my_layers As Layer.LayerManager = workpart.Layers

        For Each obj As DisplayableObject In theSession.Parts.Work.Bodies

            If my_layers.GetState(obj.Layer) < 2 Then
                If obj.IsBlanked = False Then ' only check visible objects
                    If obj.GetType.ToString = "NXOpen.Body" Then ' only check object types of body
                        Dim my_body As Body = CType(obj, Body)

                        Dim my_faces() As Face = my_body.GetFaces() 'get all faces of the body

                        Dim i As Integer = 0

                        For i = 0 To my_faces.Length - 1
                            Dim count As Integer = 1
                            Dim params(1) As Double
                            params(0) = 0.5
                            params(1) = 0.5

                            get_face_rad_AFP(my_faces(i), params)
                            get_face_rad_EF(my_faces(i), params)
                            get_face_rad(my_faces(i), params(0), params(1))
                    End If
                End If
            End If

        ' TODO: Add your application code here 

    End Sub
    Public Function get_face_rad_AFP(ByVal my_face As Face, ByVal uv() As Double) As Double

        Dim my_point(2) As Double
        Dim my_u1(2) As Double
        Dim my_u2(2) As Double
        Dim my_v1(2) As Double
        Dim my_v2(2) As Double
        Dim my_norm(2) As Double
        Dim my_radii(1) As Double

            theUfSession.Modl.AskFaceProps(my_face.Tag, uv, my_point, my_u1, my_v1, my_u2, my_v2, my_norm, my_radii)
        Catch ex As Exception

        End Try

    End Function

    Public Function get_face_rad_EF(ByVal my_face As Face, ByVal uv() As Double) As Double

        Dim surfaceValues As NXOpen.UF.ModlSrfValue = New NXOpen.UF.ModlSrfValue()
        Dim mode As Integer = NXOpen.UF.UFConstants.UF_MODL_EVAL_ALL

            theUfSession.Modl.EvaluateFace(my_face.Tag, mode, uv, surfaceValues)
        Catch ex As Exception

        End Try

    End Function

    Private Function get_face_rad(ByVal my_face As Face, ByVal uval As Double, ByVal vval As Double) As Double

        Dim scalar1 As Scalar
        scalar1 = workpart.Scalars.CreateScalar(uval, Scalar.DimensionalityType.None, SmartObject.UpdateOption.WithinModeling)
        Dim scalar2 As Scalar
        scalar2 = workpart.Scalars.CreateScalar(vval, Scalar.DimensionalityType.None, SmartObject.UpdateOption.WithinModeling)
        Dim point1 As Point
        point1 = workpart.Points.CreatePoint(my_face, scalar1, scalar2, SmartObject.UpdateOption.WithinModeling)
        Dim point13d As New Point3d(point1.Coordinates.X, point1.Coordinates.Y, point1.Coordinates.Z)

        Dim geometricProperties1 As GeometricAnalysis.GeometricProperties
        Dim out_face As GeometricAnalysis.GeometricProperties.Face
        geometricProperties1 = workpart.AnalysisManager.CreateGeometricPropertiesObject()

        geometricProperties1.OutputMethod = GeometricAnalysis.GeometricProperties.OutputType.Static

        Dim status1 As GeometricAnalysis.GeometricProperties.Status

            status1 = geometricProperties1.GetFaceProperties(my_face, point13d, out_face)
        Catch ex As Exception
            theSession.ListingWindow.WriteLine("Old Function")

        End Try

        get_face_rad = 1 / out_face.InvOfMinRadiusOfCurvature
    End Function

    Public Function GetUnloadOption(ByVal dummy As String) As Integer

        'Unloads the image immediately after execution within NX
        GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately

        '----Other unload options-------
        'Unloads the image when the NX session terminates
        'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.AtTermination

        'Unloads the image explicitly, via an unload dialog
        'GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Explicitly

    End Function

End Module


the 3rd function is my old 'clunky but reliable' one.