cancel
Showing results for 
Search instead for 
Did you mean: 

Does any know why the following snap code does not work on the 2 sections of the tube?

Valued Contributor
Valued Contributor

I have a code from @Yamada from this post, everything works quite well but there are a few cases the program cannot pick some of the sections. I attached one fo the part that I have problem with: the 2 gray/nonhighlighted sections are the ones I have issue withIssue.jpg

 

 

 

 

 

The full code from Yamada

' Constructs center-line curves of tube-like surfaces, and measures their length
' Usage: run the program and select faces of type cylinder, torus, or b-surface

Option Infer On
Imports Snap, Snap.Create, Snap.UI, Snap.NX.ObjectTypes
 
Public Class MyProgram
 
   Public Shared Sub Main

      ' Create a selection dialog and set the filter
      Dim dialog = Selection.SelectObject("Select a b-surface tube face")
      dialog.SetFaceFilter(SubType.FaceBsurface, SubType.FaceCylinder, SubType.FaceTorus)

      Dim face As NX.Face = Nothing
      Dim spine As NX.Curve = Nothing

      Dim curLength As Double = 0
      Dim cumLength As Double = 0

      InfoWindow.WriteLine(" ")
      InfoWindow.WriteLine("     Current      Cumulative")
      InfoWindow.WriteLine("     =======      ==========")

      Do 
         ' Display the dialog and get faces
         Dim result = dialog.Show()

         If result.Response < 4 Then Exit Do   ' User pressed OK, Back, or Cancel

         face = result.Object
         If face IsNot Nothing Then spine = Centerline(face)

         If spine IsNot Nothing Then
            curLength = spine.ArcLength
            cumLength = cumLength + curLength
         End If

         Dim curLengthString = string.Format("{0,12:F3}", curLength)	
         Dim cumLengthString = string.Format("{0,16:F3}", cumLength)

         InfoWindow.WriteLine(curLengthString & cumLengthString)

      Loop Until face Is Nothing

   End Sub

   Public Shared Function Centerline(face As NX.Face) As NX.Curve

      Dim spine As NX.Curve = Nothing

      If face.ObjectSubType = SubType.FaceCylinder  Then spine =   CylinderCenterline(CType(face, Snap.NX.Face.Cylinder))
      If face.ObjectSubType = SubType.FaceTorus     Then spine =      TorusCenterline(CType(face, Snap.NX.Face.Torus))
      If face.ObjectSubType = SubType.FaceBsurface  Then spine =   BsurfaceCenterline(CType(face, Snap.NX.Face.Bsurface))
     
      Return spine

   End Function

   Public Shared Function BsurfaceCenterline(face As NX.Face.Bsurface) As NX.Spline

      ' Determine which is the "tube" direction (u or v).  For tubes created in NX, 
      ' we always have dir = 2, but for surfaces imported from other systems, it could be either.
      Dim dir As Integer = GetTubeDirection(face)

      ' Create two curves running along the tube, on diametrically opposite sides
      Dim side1 As NX.Spline = Nothing
      Dim side2 As NX.Spline = Nothing

      If dir = 2  ' The u = constant iso-curves run along the tube
         side1 = face.IsoCurveU(0.25)(0)
         side2 = face.IsoCurveU(0.75)(0)
      End If

      If dir = 1  ' The v = constant iso-curves run along the tube
         side1 = face.IsoCurveV(0.25)(0)
         side2 = face.IsoCurveV(0.75)(0)
      End If

      Dim centerline As NX.Spline = Nothing

      If dir <> 0
         ' Create a ruled surface between the two side iso-curves
         Dim cross As NX.Ruled = Ruled(side1, side2)
         Dim crossSurf As Snap.NX.Face.Bsurface = cross.Faces(0)
       
         ' The tube centerline is the center curve of the ruled surface
         centerline = crossSurf.IsoCurveV(0.5)(0)
 
         cross.Delete()
         side1.Delete()
         side2.Delete()
      End If
      
      Return centerline

   End Function

   Public Shared Function CylinderCenterline(face As NX.Face.Cylinder) As NX.Line

      Dim box = face.BoxUV
      Dim v0 As Double = box.MinV
      Dim v1 As Double = box.MaxV

      Dim p0, q0, c0, p1, q1, c1 As Position

      ' Points p and q are diametrically opposite, and c is their mid-point, so is on the centerline
      p0  = face.Position(90, v0)   :   q0  = face.Position(270, v0)   :   c0 = 0.5*(p0 + q0)
      p1  = face.Position(90, v1)   :   q1  = face.Position(270, v1)   :   c1 = 0.5*(p1 + q1)

      Return Snap.Create.Line(c0, c1)

   End Function

   Public Shared Function TorusCenterline(face As NX.Face.Torus) As NX.Arc

      Dim box = face.BoxUV
      Dim u0 As Double = box.MinU
      Dim u1 As Double = box.MaxU
      Dim um As Double = 0.5*(u0 + u1)

      Dim p0, q0, c0, p1, q1, c1, pm, qm, cm As Position

      ' Points p and q are on opposite sidesof torus tube, and c is on the torus centerline
      p0  = face.Position(u0, 90)   :   q0  = face.Position(u0, 270)   :   c0 = 0.5*(p0 + q0)
      pm  = face.Position(um, 90)   :   qm  = face.Position(um, 270)   :   cm = 0.5*(pm + qm)
      p1  = face.Position(u1, 90)   :   q1  = face.Position(u1, 270)   :   c1 = 0.5*(p1 + q1)

      Return Snap.Create.Arc(c0, cm, c1)

   End Function

   ''' <summary>Determines which direction (u or v) runs along the tube</summary>
   ''' <param name="face">The b-surface</param>
   ''' <returns>Direction indicator</returns>
   ''' <remarks>
   '''    dir = 1 means the iso-curves v = constant run along the tube, u = constant curves are circles
   '''    dir = 2 means the iso-curves u = constant run along the tube, v = constant curves are circles
   '''    dir = 0 means the b-surface doesn't look much like a tube at all
   ''' </remarks>
   Private Shared Function GetTubeDirection(face As NX.Face.Bsurface) As Integer

      Dim p00 = face.Position(0,0)   :   Dim p01 = face.Position(0,1)
      Dim p10 = face.Position(1,0)   :   Dim p11 = face.Position(1,1)

      Dim distU0 = Snap.Position.Distance(p00, p01)   'Distance between end-points of edge u = 0
      Dim distU1 = Snap.Position.Distance(p10, p11)   'Distance between end-points of edge u = 1
      Dim distV0 = Snap.Position.Distance(p00, p10)   'Distance between end-points of edge v = 0
      Dim distV1 = Snap.Position.Distance(p01, p11)   'Distance between end-points of edge v = 1

      Dim eps As Double = 0.0001

      Dim dir As Integer = 0
      If distU0 < eps And distU1 < eps Then dir = 1    ' edges u=0 and u=1 are closed (circles) 
      If distV0 < eps And distV1 < eps Then dir = 2    ' edges v=0 and v=1 are closed (circles) 

      Return dir

   End Function

End Class

 

 

8 REPLIES

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Honored Contributor
Honored Contributor

Those particular faces are of a type that the SNAP code is not currently designed to handle. If you use the "optimize face" command on the body faces (always a good idea when dealing with imported geometry), they will be converted to something the SNAP code will handle. The "heal geometry" command would also probably work in this case.

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Valued Contributor
Valued Contributor

Thanks, I hit my head a few times as did not have any clue why it could happen so I just used the length measurement tool to estimate the length.  

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Siemens Phenom Siemens Phenom
Siemens Phenom

Those faces you can't pick ... what surface type are they ??

 

Your selection code filters for FaceBsurface, FaceCylinder,  and FaceTorus.

Maybe you need to include FaceRevolved, too (or whatever type you find the non-selectable faces to be). As far as I know, Snap can handle *every* face type in selection.

 

Or, as cowski said, run a heal/optimize function, and it will probably convert the mystery faces into cylinders.

 

山田
yamada

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Honored Contributor
Honored Contributor

@Yamada,

Info -> object reports the faces as "Surface Type (Non-Parametric) Extruded". Optimize face converts it to "Surface Type (Non-Parametric) Trimmed Cylindrical".

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Siemens Phenom Siemens Phenom
Siemens Phenom

Aaah, I see. Then I guess the code needs to be expanded to include both Extruded and Revolved surface types. Changing the selection filtering is trivial, but it will take a bit of work to calculate centerline lengths. I will make the additions when I get a chance. Meanwhile, use Optimize face.

山田
yamada

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Valued Contributor
Valued Contributor

@Yamada, couldyou include the 

 

Public Shared Function CylinderFaceExtruded(face As NX.Face.Extruded) As NX.Line

In the line create function?  

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Valued Contributor
Valued Contributor

@Yamada, ah I did not see your post when I posted my additional request.

Re: Does any know why the following snap code does not work on the 2 sections of the tube?

Siemens Phenom Siemens Phenom
Siemens Phenom

Adding support for Extruded faces was easy. Here is the code:

 

' Constructs center-line curves of tube-like surfaces, and measures their length
' Usage: run the program and select faces of type cylinder, torus, extruded, or b-surface

Option Infer On
Imports Snap, Snap.Create, Snap.UI, Snap.NX.ObjectTypes
 
Public Class MyProgram
 
   Public Shared Sub Main

      ' Create a selection dialog and set the filter
      Dim dialog = Selection.SelectObject("Select a tube face")
      dialog.SetFaceFilter(SubType.FaceBsurface, SubType.FaceCylinder, SubType.FaceTorus, SubType.FaceExtruded)

      Dim face As NX.Face = Nothing
      Dim spine As NX.Curve = Nothing

      Dim curLength As Double = 0
      Dim cumLength As Double = 0

      InfoWindow.WriteLine(" ")
      InfoWindow.WriteLine("     Current      Cumulative")
      InfoWindow.WriteLine("     =======      ==========")

      Do 
         ' Display the dialog and get faces
         Dim result = dialog.Show()

         If result.Response < 4 Then Exit Do   ' User pressed OK, Back, or Cancel

         face = result.Object
         If face IsNot Nothing Then spine = Centerline(face)

         If spine IsNot Nothing Then
            curLength = spine.ArcLength
            cumLength = cumLength + curLength
         End If

         Dim curLengthString = string.Format("{0,12:F3}", curLength)	
         Dim cumLengthString = string.Format("{0,16:F3}", cumLength)

         InfoWindow.WriteLine(curLengthString & cumLengthString)

      Loop Until face Is Nothing

   End Sub

   Public Shared Function Centerline(face As NX.Face) As NX.Curve

      Dim spine As NX.Curve = Nothing

      If face.ObjectSubType = SubType.FaceCylinder  Then spine =    ExtrudeCenterline(face) 
      If face.ObjectSubType = SubType.FaceExtruded  Then spine =    ExtrudeCenterline(face)
      If face.ObjectSubType = SubType.FaceTorus     Then spine =      TorusCenterline(CType(face, Snap.NX.Face.Torus))
      If face.ObjectSubType = SubType.FaceBsurface  Then spine =   BsurfaceCenterline(CType(face, Snap.NX.Face.Bsurface))
     
      Return spine

   End Function

   Public Shared Function BsurfaceCenterline(face As NX.Face.Bsurface) As NX.Spline

      ' Determine which is the "tube" direction (u or v).  For tubes created in NX, 
      ' we always have dir = 2, but for surfaces imported from other systems, it could be either.
      Dim dir As Integer = GetTubeDirection(face)

      ' Create two curves running along the tube, on diametrically opposite sides
      Dim side1 As NX.Spline = Nothing
      Dim side2 As NX.Spline = Nothing

      If dir = 2  ' The u = constant iso-curves run along the tube
         side1 = face.IsoCurveU(0.25)(0)
         side2 = face.IsoCurveU(0.75)(0)
      End If

      If dir = 1  ' The v = constant iso-curves run along the tube
         side1 = face.IsoCurveV(0.25)(0)
         side2 = face.IsoCurveV(0.75)(0)
      End If

      Dim centerline As NX.Spline = Nothing

      If dir <> 0
         ' Create a ruled surface between the two side iso-curves
         Dim cross As NX.Ruled = Ruled(side1, side2)
         Dim crossSurf As Snap.NX.Face.Bsurface = cross.Faces(0)
       
         ' The tube centerline is the center curve of the ruled surface
         centerline = crossSurf.IsoCurveV(0.5)(0)
 
         cross.Delete()
         side1.Delete()
         side2.Delete()
      End If
      
      Return centerline

   End Function

   ' This function handles both Extruded surfaces and cylinders
   Public Shared Function ExtrudeCenterline(face As NX.Face) As NX.Line

      Dim box = face.BoxUV

      Dim u0 As Double = box.MinU + 0.25*(box.MaxU - box.MinU)
      Dim u1 As Double = box.MinU + 0.75*(box.MaxU - box.MinU)

      Dim v0 As Double = box.MinV
      Dim v1 As Double = box.MaxV

      Dim p0, q0, c0, p1, q1, c1 As Position

      ' Points p and q are diametrically opposite, and c is their mid-point, so is on the centerline
      p0  = face.Position(u0, v0)   :   q0  = face.Position(u1, v0)   :   c0 = 0.5*(p0 + q0)
      p1  = face.Position(u0, v1)   :   q1  = face.Position(u1, v1)   :   c1 = 0.5*(p1 + q1)

      Return Snap.Create.Line(c0, c1)

   End Function

   Public Shared Function TorusCenterline(face As NX.Face.Torus) As NX.Arc

      Dim box = face.BoxUV
      Dim u0 As Double = box.MinU
      Dim u1 As Double = box.MaxU
      Dim um As Double = 0.5*(u0 + u1)

      Dim p0, q0, c0, p1, q1, c1, pm, qm, cm As Position

      ' Points p and q are on opposite sides of torus tube, and c is on the torus centerline
      p0  = face.Position(u0, 90)   :   q0  = face.Position(u0, 270)   :   c0 = 0.5*(p0 + q0)
      pm  = face.Position(um, 90)   :   qm  = face.Position(um, 270)   :   cm = 0.5*(pm + qm)
      p1  = face.Position(u1, 90)   :   q1  = face.Position(u1, 270)   :   c1 = 0.5*(p1 + q1)

      Return Snap.Create.Arc(c0, cm, c1)

   End Function

   ''' <summary>Determines which direction (u or v) runs along the tube</summary>
   ''' <param name="face">The b-surface</param>
   ''' <returns>Direction indicator</returns>
   ''' <remarks>
   '''    dir = 1 means the iso-curves v = constant run along the tube, u = constant curves are circles
   '''    dir = 2 means the iso-curves u = constant run along the tube, v = constant curves are circles
   '''    dir = 0 means the b-surface doesn't look much like a tube at all
   ''' </remarks>
   Private Shared Function GetTubeDirection(face As NX.Face.Bsurface) As Integer

      Dim p00 = face.Position(0,0)   :   Dim p01 = face.Position(0,1)
      Dim p10 = face.Position(1,0)   :   Dim p11 = face.Position(1,1)

      Dim distU0 = Snap.Position.Distance(p00, p01)   'Distance between end-points of edge u = 0
      Dim distU1 = Snap.Position.Distance(p10, p11)   'Distance between end-points of edge u = 1
      Dim distV0 = Snap.Position.Distance(p00, p10)   'Distance between end-points of edge v = 0
      Dim distV1 = Snap.Position.Distance(p01, p11)   'Distance between end-points of edge v = 1

      Dim eps As Double = 0.0001

      Dim dir As Integer = 0
      If distU0 < eps And distU1 < eps Then dir = 1    ' edges u=0 and u=1 are closed (circles) 
      If distV0 < eps And distV1 < eps Then dir = 2    ' edges v=0 and v=1 are closed (circles) 

      Return dir

   End Function

End Class
山田
yamada