Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations waross on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Journal - Listing Intersections between multiple curves and multiple surfaces 1

Status
Not open for further replies.

alj722

Aerospace
Nov 4, 2004
36
0
0
US
Greetings,

I'm working on a Journal file (haven't done much of this before) where I do the following:
1) Select a bunch of lines
2) Select a bunch of faces
3) Pick an origin point (or simply use the WCS location or the start point of one of the lines)
4) Dump out a file (preferably a comma separated text file) that lists:
Line ID: (or startpoint/endpoint)
Face ID:
Face's Owning Body: (for the purpose of getting the body's material)
Intersection Point: (maybe with some flag such as None, when no intersection)

I have it so I can select all the curves and select all the faces and loop through them, but I can't figure out how to get the intersection point. Attached is the code (some of it adapted from a sample on NXJournaling.com). Anyone done anything like this. Also, is anyone aware of a class on writing NX Journals?

Drew Jones

Code:
Option Strict Off  
Imports System  
Imports NXOpen  
Imports NXOpen.UF  
Imports NXOpen.Assemblies  

Module Module1  

    Sub Main()  

        Dim theSession As Session = Session.GetSession()  
        Dim workPart As Part = theSession.Parts.Work  
        Dim lw As ListingWindow = theSession.ListingWindow  
        lw.Open()  

        Dim myVectors() As TaggedObject  

        If SelectVectors("Select Vectors", myVectors) = Selection.Response.Cancel Then  
            Return  
        End If  

        Dim myFaces() As TaggedObject  

        If SelectFaces("Select Faces", myFaces) = Selection.Response.Cancel Then  
            Return  
        End If  

        For Each tempVector As Line In myVectors  
             lw.WriteLine("Curve Name: " & tempVector.Name)  
             lw.WriteLine(tempVector.StartPoint.ToString)
             lw.WriteLine(tempVector.EndPoint.ToString)
             For Each tempFace As Face In myFaces
                 lw.WriteLine("Owning Body: " & tempFace.GetBody.OwningComponent.ToString)
                 lw.WriteLine("Face Color: " & tempFace.Color)
' THIS DOESN'T WORK:                 lw.WriteLine("Intersection: " & UFCurve.Intersect(tempVector,tempFace,tempVector.StartPoint))
             Next  
        Next  

    End Sub  

    Function SelectVectors(ByVal prompt As String, ByRef selObj() As TaggedObject) As Selection.Response  

        Dim theUI As UI = UI.GetUI  
        Dim title As String = "Select Vectors"  
        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 = UFConstants.UF_line_type  
            .Subtype = UFConstants.UF_line_normal_subtype  
        End With  

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, _  
         title, scope, selAction, _  
         includeFeatures, keepHighlighted, selectionMask_array, _  
         selobj)  
        If resp = Selection.Response.Ok Then  
            Return Selection.Response.Ok  
        Else  
            Return Selection.Response.Cancel  
        End If  

    End Function  

    Function SelectFaces(ByVal prompt As String, ByRef selObj() As TaggedObject) As Selection.Response  

        Dim theUI As UI = UI.GetUI  
        Dim title As String = "Select Faces"  
        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 = UFConstants.UF_face_type  
'            .Subtype = UFConstants.UF_line_normal_subtype  
        End With  

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, _  
         title, scope, selAction, _  
         includeFeatures, keepHighlighted, selectionMask_array, _  
         selobj)  
        If resp = Selection.Response.Ok 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
 
Replies continue below

Recommended for you

I have made several corrections to get the journal to run for you. Hopefully I have written it to help you understand what is happening.

Code:
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies

Module Intersect1
    Sub Main()
        Dim theSession As Session = Session.GetSession()
        Dim workPart As Part = theSession.Parts.Work
        Dim lw As ListingWindow = theSession.ListingWindow
        Dim ufs As UFSession = UFSession.GetUFSession()
        lw.Open()
        Dim myVectors(-1) As TaggedObject
        If SelectVectors("Select Vectors", myVectors) = Selection.Response.Cancel Then
            Return
        End If
        Dim myFaces(-1) As TaggedObject
        If SelectFaces("Select Faces", myFaces) = Selection.Response.Cancel Then
            Return
        End If
        Dim mybody As Body = Nothing
        Dim mystartpoint(2) As Double
        Dim myintersectpoint(2) As Double
        Dim myfaceparms(1) As Double
        Dim intersectdata1 As NXOpen.UF.UFCurve.IntersectInfo = Nothing
        Dim intersectfound1 As Integer = Nothing
        For Each tempVector As Line In myVectors
            mystartpoint(0) = tempVector.StartPoint.X
            mystartpoint(1) = tempVector.StartPoint.Y
            mystartpoint(2) = tempVector.StartPoint.Z
            lw.WriteLine("Curve Name: " & tempVector.Name)
            lw.WriteLine(tempVector.StartPoint.ToString)
            lw.WriteLine(tempVector.EndPoint.ToString)
            For Each tempFace As Face In myFaces
                ufs.Curve.Intersect(tempVector.Tag, tempFace.Tag, mystartpoint, intersectdata1)
                If intersectdata1.type_of_intersection = 0 Then
                    ' no intersection found
                ElseIf intersectdata1.type_of_intersection = 1 Then
                    ' 3D intersection found
                ElseIf intersectdata1.type_of_intersection = 2 Then
                    ' 2D intersection found
                End If
                If intersectdata1.type_of_intersection = 1 Then
                    myintersectpoint(0) = intersectdata1.curve_point(0)
                    myintersectpoint(1) = intersectdata1.curve_point(1)
                    myintersectpoint(2) = intersectdata1.curve_point(2)
                    myfaceparms(0) = intersectdata1.entity_parms(0)
                    myfaceparms(1) = intersectdata1.entity_parms(1)
                End If
                mybody = tempFace.GetBody
                lw.WriteLine("Owning Body: " & mybody.ToString)
                lw.WriteLine("Face Color: " & tempFace.Color)
                If intersectdata1.type_of_intersection = 0 Then
                    lw.WriteLine("No intersection found")
                ElseIf intersectdata1.type_of_intersection = 1 Then
                    lw.WriteLine("Intersection point: X = " & myintersectpoint(0).ToString & vbCrLf & _
                                 "                    Y = " & myintersectpoint(1).ToString & vbCrLf & _
                                 "                    Z = " & myintersectpoint(2).ToString)
                End If
                lw.WriteLine(vbCrLf)
            Next
        Next

    End Sub

    Function SelectVectors(ByVal prompt As String, ByRef selObj() As TaggedObject) As Selection.Response

        Dim theUI As UI = UI.GetUI
        Dim title As String = "Select Vectors"
        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 = UFConstants.UF_line_type
            .Subtype = 0
        End With

        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selObj)
        If resp = Selection.Response.Ok Then
            Return Selection.Response.Ok
        Else
            Return Selection.Response.Cancel
        End If

    End Function

    Function SelectFaces(ByVal prompt As String, ByRef selObj() As TaggedObject) As Selection.Response

        Dim theUI As UI = UI.GetUI
        Dim title As String = "Select Faces"
        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 = UFConstants.UF_face_type
            .Subtype = 0
        End With
        Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, _
         title, scope, selAction, _
         includeFeatures, keepHighlighted, selectionMask_array, _
         selObj)
        If resp = Selection.Response.Ok 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

Frank Swinkels
 
Frank! This is exactly what I was trying to do. I'll start tinkering with it today (and trying to fully understand your steps). Are you aware of training on NX Journal files? I was thinking about taking a VB.NET class, but I wasn't sure how applicable it would be. I'm just hacking and I would like to really learn how to do it properly.

Thanks again!

Drew
 
Thanks to Frank this is almost doing what I need. It is so close. Unfortunately I discovered a problem with the way NX handles intersections. NX will provide an intersection even if it isn't actually piercing the surface. For example, if there is a hole in the surface and the vector goes through the hole, it still gives you an intersection point. For normal work, this is great. For this application, that is a problem. I can't find a way to get around that. I've been looking for a way to check to make sure the intersection point is inside the body that the face is associated to so that if it is not in the body, then it should be filtered out, but I've not cracked that one yet. I've attached the sample assembly I'm using for testing this, the VB code and the spreadsheet in case anyone has a guess on how I might work around this.

The final product for this is a spreadsheet that follows each of the vectors outward from the start point and records in a table where the vector pierces a solid, what the material is, and where it exits the other side. This will eventually be used to roughly approximate which areas in the model are most vulnerable to radiation in space by tracing particles along the vector and through the various layers to the spot being analyzed.

Thanks for any and all help on this...

Drew
 
 http://files.engineering.com/getfile.aspx?folder=e8ee83e4-0365-4e7d-b0d2-14568699bacf&file=Pierce_Vector_Intersect.zip
This should work to eliminate false positives of an intersection:
Measure the distance between the vector and the solid. If not 0, they don't touch so ignore.
myDistance = workPart.MeasureManager.NewDistance(unit1, MeasureManager.MeasureType.Minimum, mybody, tempVector)
Then check to make sure the intersection point actually is on the curve (to eliminate extension intersection results)
 
I think you should be using the following method which is a wrapper function from user functions. The method is

Public Sub TraceARay ( _
num_bodies As Integer, _
bodies As Tag(), _
origin As Double(), _
direction As Double(), _
transform As Double(), _
num_desired As Integer, _
<OutAttribute> ByRef num_results As Integer, _
<OutAttribute> ByRef hit_list As UFModl..::..RayHitPointInfo() _
)

When a ray is created from a point, along a vector, the bodies that it intersects can be checked for hit body, hit face and hit point. So that with your example the outerbody is not intersected with one line/vector and the other line/vector does intersect the outerbody. Both lines intersect the inner body.

The TraceARay method does not need the lines as NX objects. It uses a vector from a point/position. From the output of the method we can get the bodies we intersect with, the point of intersection for a particular direction. The data can be saved to an external spreadsheet. One possible limitation is that the TraceARay mehod works on the current work part. Not that this can be worked around but if you have multiple outer bodies which are in multiple components and points are in other components then we need not only change work parts but also need to allow for components position and orientation.

Regards

Frank Swinkels
 
That TraceARay sounds like it might be what I need. I got the brute force method working and it is giving me clean results so I'll have to try the TraceARay method on the next go-around. Here is the code in case it is of any use to anyone. It isn't pretty, but it does what I need:

Code:
Option Strict Off
Imports System
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies

Module Intersect1
     Sub Main()
         Dim theSession As Session = Session.GetSession()
         Dim workPart As Part = theSession.Parts.Work
         Dim lw As ListingWindow = theSession.ListingWindow
         Dim ufs As UFSession = UFSession.GetUFSession()
         lw.Open()
         Dim myVectors(-1) As TaggedObject
         If SelectVectors("Select Vectors", myVectors) = Selection.Response.Cancel Then
             Return
         End If
         Dim myFaces(-1) As TaggedObject
         If SelectFaces("Select Faces", myFaces) = Selection.Response.Cancel Then
             Return
         End If
         Dim mybody As Body = Nothing
         Dim mystartpoint(2) As Double
         Dim myCenterPoint(2) as Double
         Dim myDistToIntersect(2) as Double
         Dim myendpoint(2) as Double
         Dim myintersectpoint(2) As Double
         Dim myfaceparms(1) As Double
         Dim intersectdata1 As NXOpen.UF.UFCurve.IntersectInfo = Nothing
         Dim intersectfound1 As Integer = Nothing
         Dim myMeasure As MeasureManager = workPart.MeasureManager
         Dim myDistance As MeasureDistance
         Dim CheckDistVectorLen As Double
         Dim CheckDistIntToStart As Double
         Dim CheckDistIntToEnd As Double
         Dim CheckDistSum as Double
         Dim unit1 As Unit
         Dim intNumDig as Integer = 5
         Dim myMaterial as String = "unset"
         Dim intCount as Integer = 0
'            Figure out what the units are.
         If workPart.PartUnits = BasePart.Units.Inches Then  
             unit1 = CType(workPart.UnitCollection.FindObject("Inch"), Unit)  
         Else  
             unit1 = CType(workPart.UnitCollection.FindObject("MilliMeter"), Unit)  
         End If  
'            Walk through each curve that has been selected to represent vectors
         For Each tempVector As Line In myVectors
'                   Extract the Start Point and End Point and calculate the Curve Length for a later check
             mystartpoint(0) =  tempVector.StartPoint.X
             mystartpoint(1) = tempVector.StartPoint.Y
             mystartpoint(2) = tempVector.StartPoint.Z
             myendpoint(0) = tempVector.EndPoint.X
             myendpoint(1) = tempVector.EndPoint.Y
             myendpoint(2) = tempVector.EndPoint.Z
             CheckDistVectorLen=((mystartpoint(0)-myendpoint(0))^2+(mystartpoint(1)-myendpoint(1))^2+(mystartpoint(1)-myendpoint(1))^2)^.5
'                  Compare each vector against each face
             For Each tempFace As Face In myFaces
'                        Check to see it intersects
                 ufs.Curve.Intersect(tempVector.Tag, tempFace.Tag, mystartpoint, intersectdata1)
                 If intersectdata1.type_of_intersection = 1 Then
'                                 Found a 3D Intersection, now get info about it.
'                                 If this is the first time through, dump out the center point (Start Point for the Vectors) and Column Headers
                     if intCount = 0 then
'                                      Put the Center Point label in quotes since it has commas in the text which will foul things up if read into Excel as a CSV file
                         lw.WriteLine("Save This as a CSV file so it can be imported into Excel")
                         lw.WriteLine(ControlChars.Quote & "Center Point (X1, Y1, Z1):" & ControlChars.Quote)
'                                      Use the Start Point of the First Curve as the Center Point (May Want to Add Selecting Start point in Future)
'                                      Currently the vectors need to be created from the center point outward for this to work
                         myCenterPoint(0) = mystartpoint(0)
                         myCenterPoint(1) = mystartpoint(1)
                         myCenterPoint(2) = mystartpoint(2)
                         lw.WriteLine(FormatNumber(myCenterPoint(0),intNumDig,,,TriState.True).ToString & "," & _
                                      FormatNumber(myCenterPoint(1),intNumDig,,,TriState.True).ToString & "," & _
                                      FormatNumber(myCenterPoint(2),intNumDig,,,TriState.True).ToString)
                         lw.WriteLine("Vector,X2,Y2,Z2,Face,Component,Material,IntX,IntY,IntZ,Dist")
                         intCount = intCount + 1
                     end if
                     myintersectpoint(0) = intersectdata1.curve_point(0)
                     myintersectpoint(1) = intersectdata1.curve_point(1)
                     myintersectpoint(2) = intersectdata1.curve_point(2)
                     myDistToIntersect(0) = ((myintersectpoint(0)-myCenterPoint(0))^2+(myintersectpoint(1)-myCenterPoint(1))^2+(myintersectpoint(2)-myCenterPoint(2))^2)^.5
                     myfaceparms(0) = intersectdata1.entity_parms(0)
                     myfaceparms(1) = intersectdata1.entity_parms(1)
'                               Grab the Body associated with the Face
                     mybody = tempFace.GetBody
'                                Grab the Body Material
                     myMaterial=myBody.GetStringAttribute("MATERIAL")
'                                 Check to make sure the curve actually intersects the body by measuring the minimun distance from the curve to the body
'                                 A distance of 0 means they touch
                     myDistance = workPart.MeasureManager.NewDistance(unit1, MeasureManager.MeasureType.Minimum, mybody, tempVector)
                     if myDistance.Value.ToString = 0 then
'                                      Use the distance between the intersection point and each vector end point to check to make sure the intersection is on the curve
'                                      If the sum of the distances match the overall length of the vector, the intersection point lies on the curve.
'                                      Reduce the number of digits so that round off errors are eliminated.
                         CheckDistIntToStart = ((mystartpoint(0)-myintersectpoint(0))^2+(mystartpoint(1)-myintersectpoint(1))^2+(mystartpoint(1)-myintersectpoint(1))^2)^.5
                         CheckDistIntToEnd = ((myendpoint(0)-myintersectpoint(0))^2+(myendpoint(1)-myintersectpoint(1))^2+(myendpoint(1)-myintersectpoint(1))^2)^.5
                         CheckDistSum = CheckDistIntToStart + CheckDistIntToEnd
                         If FormatNumber(CheckDistVectorLen,intNumDig,,,TriState.True) = FormatNumber(CheckDistSum,intNumDig,,,TriState.True) then
'                                            This intersection point should be on the body so formating the numbers and dump everyting out in comma separated format
  						     lw.WriteLine(tempVector.Name & "," & _
                                     FormatNumber(myendpoint(0),intNumDig,,,TriState.True).ToString & "," & _
                                     FormatNumber(myendpoint(1),intNumDig,,,TriState.True).ToString & "," & _
                                     FormatNumber(myendpoint(2),intNumDig,,,TriState.True).ToString & "," & _
                                     tempface.ToString & "," & _
                                     mybody.OwningComponent.Name & "," & _
                                     ControlChars.Quote & myMaterial & ControlChars.Quote & "," & _
                                     FormatNumber(myintersectpoint(0),intNumDig,,,TriState.True).ToString & "," & _
                                     FormatNumber(myintersectpoint(1),intNumDig,,,TriState.True).ToString & "," & _
                                     FormatNumber(myintersectpoint(2),intNumDig,,,TriState.True).ToString & "," & _
                                     FormatNumber(myDistToIntersect(0),intNumDig,,,TriState.True).ToString & vbCrLf)
                         End if
                     End if
                 End if
             Next
         Next
     End Sub

     Function SelectVectors(ByVal prompt As String, ByRef selObj() As TaggedObject) As Selection.Response
         Dim theUI As UI = UI.GetUI
         Dim title As String = "Select Vectors"
         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 = UFConstants.UF_line_type
             .Subtype = 0
         End With
         Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, _
             title, scope, selAction, _
             includeFeatures, keepHighlighted, selectionMask_array, _
             selObj)
         If resp = Selection.Response.Ok Then
             Return Selection.Response.Ok
         Else
            Return Selection.Response.Cancel
         End If
     End Function

     Function SelectFaces(ByVal prompt As String, ByRef selObj() As TaggedObject) As Selection.Response
         Dim theUI As UI = UI.GetUI
         Dim title As String = "Select Faces"
         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 = UFConstants.UF_face_type
             .Subtype = 0
         End With
         Dim resp As Selection.Response = theUI.SelectionManager.SelectTaggedObjects(prompt, _
             title, scope, selAction, _
             includeFeatures, keepHighlighted, selectionMask_array, _
             selObj)
         If resp = Selection.Response.Ok 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
 
Status
Not open for further replies.
Back
Top