Obtaining TinSurfaceTriangle Index (Plus Vertex Index)

TerryDotson
Mentor
Mentor

Obtaining TinSurfaceTriangle Index (Plus Vertex Index)

TerryDotson
Mentor
Mentor

I am trying to obtain the index (integer) for TinSurfaceTriangle objects along with the (3) three index values of the vertices.  These properties are not listed in the API however they do appear in the IDE watch window.

 

capture.png

 

I've tried Reflection PropertyInfo and CallByName with no luck.  I know I can use the coordinates of the vertices to find the index in the Points collection but that is slow even with BinarySearch on a sorted list (especially on extremely large TINs).

 

So if the IDE can show these values in the watch window, why can't we obtain them in code?

0 Likes
Reply
546 Views
8 Replies
Replies (8)

david.silva
Contributor
Contributor

Hi, this is the way I use to get it:

 

First, using reflection, I get the PropertyInfo of the “Index" property. Then you get the value of that PropertyInfo referring to the vertex you want.

 

A few notes: This property isn’t available in the APi because it changes every time the surface is built or changed, so you need to be careful about that and prevent any changes to the surface while your code is running using the vertices indexes.

 

Also, beware that the vertices’ “Index”, which is an integer, may or may not be fully consecutive. I found this the hard way, trying to find a bug…

 

Here’s the code I’m using:

''' <summary>
''' Returns the PropertyInfo to use in GetIndex Extension Function (using reflection).
''' </summary>
''' <param name="vertex">The instance to which the method applies.</param>
''' <returns>The PropertyInfo corresponding to the Vertex Index.</returns>
<System.Runtime.CompilerServices.Extension()>
Public Function GetIndexPropertyInfo(vertex As TinSurfaceVertex) As PropertyInfo

    Dim arrayPropertyInfo() As PropertyInfo = vertex.GetType().GetProperties(BindingFlags.NonPublic Or BindingFlags.Instance)

    For Each prop As PropertyInfo In arrayPropertyInfo
        If prop.Name.Equals("Index") Then
            Return prop
        End If
    Next
    Return Nothing
End Function

''' <summary>
''' Returns the vertex index in the surface (using reflection).
''' </summary>
''' <param name="vertex">The instance to which the method applies.</param>
''' <param name="IndexPropertyInfo">The PropertyInfo corresponding to the Vertex Index.</param>
''' <returns>The corresponding index.</returns>
<System.Runtime.CompilerServices.Extension()>
Public Function GetIndex(vertex As TinSurfaceVertex, IndexPropertyInfo As PropertyInfo) As Integer
    Return IndexPropertyInfo.GetValue(vertex) 
End Function


'SAMPLE USAGE

 'get propertyinfo through reflection to gain access to the property index
  Dim propIndex As Reflection.PropertyInfo = SourceVertex.GetIndexPropertyInfo

  ' If we can't get propertyinfo then we can't find the index of the Vertex
  If propIndex.IsNull Then
      Throw New Exception("TinSurfaceVertex Index PropertyInfo not found.")
  End If
  
  'get the indexes of the surface's vertices
  For Each vertex As TinSurfaceVertex In Surface.Vertices
      Dim index As Integer = vertex.GetIndex(propIndex)
  Next

Anonymous
Not applicable

that really helps. @david.silva @TerryDotson 

would you please tell me how I can see the "Index" in the VSstudio. I cant see that in my IDE...

IDE with not index property.png

 

0 Likes

TerryDotson
Mentor
Mentor

See my image at the top, in the IDE (only) the Index is a child of TinSurfaceTriangle and TinSurfaceVertex, it is not displayed under TinSurfaceEdge (your branch).

0 Likes

david.silva
Contributor
Contributor

You can get the TinSurfaceVertex using several ways. 

A few notes: Each Triangle has 3 vertices and as many edges. Each vertex can be common to several triangles but each edge may be common to 2 triangles at most and share 2 vertices from each triangle. 

As I recall, when you get the triangle's vertices they'll be oriented CCW which means that you should be careful comparing edges because the same edge that separates 2 triangles will have different start and end vertices depending on which triangle you did get it from.

 

@TerryDotson : did my previous answer helped you? If so please mark this topic as answered. Thanks.

 

0 Likes

TerryDotson
Mentor
Mentor

The Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance parameters did get the Index and it matches the values displayed in the IDE.  However there are two problems, one serious.

 

  1. Non Serious: The access time was no better than a good mass points container class using sort/binarysearch on a test of 40,000 triangles.  A test on much larger surfaces may flip that.  This method also allows it to  completely exclude reflection calls.
  2. Serious:  The index value on some returned numbers that exceeds the number of vertices!  Take a look at this screen capture where Vertex1.Index refers to 20464 which is outside the range of elements.  I found this to be the case on two separate drawings, rebuilding the surface was no help.

capture.png

 

So thanks for the effort but for now I'm sticking with my existing BinarySearch method which gives consistently good results at a decent speed.

0 Likes

david.silva
Contributor
Contributor

That was the issue I mentioned in the 1st answer, which took me a while to find a bug in my program. The vertices' index number may not match the TinSurfaceTriangleCollection index. It can start with indices 1, 2, 3 and then jump to 5 or 6. My guess is that it's related with the triangulation algorithm used (that may use auxiliary construction triangles/vertices) where some vertices that are outside the surface's boundary are discarded along the way and you end up having vertices indices greater than the number of vertices of the surface. Also these indices values may change each time the surface is rebuilt.

 

I ended up building my own TinSurfaceTriangleCollection with the number of vertices (count)  equal to the index of the last surface's vertex and put each vertex in the collection's position according to its index. I agree this is quite a slow task. In my program (finding a least cost path along a surface with Dijkstra algorithm which is On2), building this collection takes about 70% of the time.

 

However, your question was how to find the vertex index property that showed up in the IDE.

0 Likes

TerryDotson
Mentor
Mentor

However, your question was how to find the vertex index property that showed up in the IDE.

True, but since they can't be trusted my problem isn't really solved is it?

0 Likes

david.silva
Contributor
Contributor

I must say that your answer made me lose all interest in continuing contributing in this forum.

0 Likes