10-11-2016 02:23 PM
Hi,
I'm writing program for changing color of dumb holes (not HOLE PACKAGE).
Let say I want to pin point all holes faces with radius 10mm. Unfortunately I'm stuck with command theUFSession.Modl.AskFaceData. Everything works great except when I want to show holes with exact radius 9mm. I'm not sure if this is the bug or I'm doing something wrong. I've tried this in NX10, NX8.5 and NX6 and it is working exactly the same.
Can somebody please check attached code. Make extrude with few holes with diameter 20mm (r10) and run the code. You will notice hole axis in holes with dia 20mm and holes listed in listing window.
Then change the holes diameter to 18mm (R9) and change the variable radius in code to 9 and run it again and nothing happens, no error,...
Thanks,
Anton
Option Strict Off Imports System Imports NXOpen Imports NXOpen.UF Module NXJournal Dim theSession As Session = Session.GetSession() Dim theUFSession As UFSession = UFSession.GetUFSession() Dim workPart As Part = theSession.Parts.Work Dim lw As ListingWindow = Nothing Public Sub Main(ByVal args As String()) lw = theSession.ListingWindow() lw.Open() For Each aBody As Body In workPart.Bodies.ToArray For Each aFace As Face In aBody.GetFaces() If aFace.SolidFaceType = Face.FaceType.Cylindrical Then Dim type As Integer = Nothing Dim axisPt(2) As Double Dim axisDir(2) As Double Dim faceBox(5) As Double Dim radius As Double = Nothing Dim rad_data As Double = Nothing Dim norm_dir As Integer = Nothing theUFSession.Modl.AskFaceData(aFace.Tag, type, axisPt, axisDir, faceBox, radius, rad_data, norm_dir) Dim pt_status As Integer = Nothing theUFSession.Modl.AskPointContainment(axisPt, aBody.Tag, pt_status) Dim uvs(3) As Double theUFSession.Modl.AskFaceUvMinmax(aFace.Tag, uvs) If radius = 10 And pt_status = 2 And (uvs(0) = 0.0) And (uvs(1) = Math.PI * 2) Then theUFSession.Disp.Conehead(UFConstants.UF_DISP_WORK_VIEW_ONLY, axisPt, axisDir, 0) lw.WriteLine("Face tag: " & aFace.Tag & " Type: " & type & " Radius: " & radius) End If End If Next Next End Sub Public Function GetUnloadOption(ByVal arg As String) As Integer Return Session.LibraryUnloadOption.Immediately End Function End Module
10-11-2016 04:23 PM
You will often run into problems like this when comparing "floating point" numbers. See the link below for one alternate strategy.
http://floating-point-gui.de/errors/comparison/
10-11-2016 04:55 PM
Hi,
I don't understand this. Why do I have problem only with radius value 9 and for all other values everything is working great?
OK I will check your link...
Any idea how to copy faces with specified radius value to DisplayableObject array?
Thanks,
10-12-2016 02:14 AM
What I do to not get into such errors is to do the test as follows
Dim testrad as Double = 9
If Math.Abs(radius -testrad) < 0.001 And pt_status = 2 And (uvs(0) = 0.0) And (uvs(1) = Math.PI * 2) Then
theUFSession.Disp.Conehead(UFConstants.UF_DISP_WORK_VIEW_ONLY, axisPt, axisDir, 0)
lw.WriteLine("Face tag: " & aFace.Tag & " Type: " & type & " Radius: " & radius)
End If
Frank Swinkels
10-12-2016 04:03 AM
Thanks Frank its working now.
I understand what is the problem , only I'm not sure why this happens only with number 9 and not with all numbers.
Thanks again,
Anton
10-12-2016 09:12 AM
If you print all the numbers to a lot of decimal places (13 or 20 or whatever) you will find out why :-)
Production: NX10.0.3.5 MP16/TC11.2
I'd rather be e-steamed than e-diseaseled
10-12-2016 09:47 AM
The problem is also known as floating point error, which is punishing any programming language since the day binary representation of real numbers was introduced.
The problem is that not all real numbers can be represented in binary format exactly.
There should be a wiki pedia page about the floating point error.
Production: NX10.0.3, VERICUT 8.2, FBM, MRL 3.1.7 | TcUA 10.1 MP7 Patch 0 (10.1.7.0) | TcVis 11.4
Development: C (ITK), .NET, Tcl/Tk Testing: NX12.0 | AWC 3.4 Preparing: NX12.0
Employees of the customers, together we are strong
How to Get the Most from Your Signature in the Community
NX Customization - Best Practice Guide
10-16-2016 10:30 PM - edited 10-16-2016 10:37 PM
Here is some alternative code that might be informative. It's an example from the Snap.NX.Face.Sense topic in the SNAP Reference Guide:
Imports Snap, Snap.Create, Snap.Topology Imports System.Drawing.Color Public Class MyProgram Public Shared Sub Main() ' Build a sample part Dim base As Snap.NX.Body = Block({0, 0, 0}, 8, 4, 2) Dim boss As Snap.NX.Body = Cylinder({2, 2, 1}, Snap.Vector.AxisZ, 2.0, 2.0).Body Dim hole As Snap.NX.Body = Cylinder({6, 2, 1}, Snap.Vector.AxisZ, 2.0, 2.0).Body Dim temp As Snap.NX.Body = Unite(base, boss).Body Dim part As Snap.NX.Body = Subtract(temp, hole).Body ' Use face senses to identify holes and bosses For Each face As NX.Face In part.Faces If face.ObjectSubType = NX.ObjectTypes.SubType.FaceCylinder Then If face.Sense = Sense.Positive Then face.Color = Red ' A boss; color it red If face.Sense = Sense.Negative Then face.Color = Green ' A hole; color it green End If Next End Sub End Class
And, as others have mentioned, you should never write "If X = Y Then ..." if X and Y are floating point numbers ("Double" in VB). Floating point numbers are just approximations, so you need some equality tolerance. Just for fun, try calculating 0.1 + 0.1 + ... + 0.1 (ten times). You won't get 1.0.