Wish: Super fast *Indicies* version of "mesh.GetNakedEdges()"

So, I need fast access to the indices of naked topology edges of a mesh.

The RhinoCommon API doesn’t provide a convenient or fast way for collecting these in an ordered structure. So what I do today, which is quite slow, is to call mesh.GetNakedEdges() and then for each edge line I perform a slow & complex “Search 'n Match” to find the corresponding edge index.

I also do need the collection of indices to be in the same grouping and order as the polyline edge groups provided by the mesh.GetNakedEdges() method. ( = §1 per edge loop, and §2 edges connected in consecutive order).

I assume that all this info is already collected before presenting the result for the GetNakedEdges() method, so why not provide some additional functions publishing the indices? Like so:

// consecutive indices, per edge loop
int[][]       edgeIndices = mesh.GetNakedEdgeIndices();
IndexPair[][] vertIndices = mesh.GetNakedEdgeTopologyVertexIndices();

and/or perhaps with both indices lists as out’s:

mesh.GetNakedEdgeTopologyIndexInfo(
        out int[]       edgeIndices, 
        out IndexPair[] vertexPairIndices);

== TWEAK ACCESS? ==

While I’m holding my breath, is there any tweakish way I could get fast access to this info, either in a unsafe way, or using any other trick?

== CURRENT SOLUTION ==

My current solution - how to improve for better speed?

var m_TE = m_mesh.TopologyEdges; // m_*** = unit variables
var ne_loops = m_mesh.GetNakedEdges();
for (int i = 0; i < ne_loops.Length; i++)
{
    var segments = ne_loops[i].GetSegments(); // for each edge loop
    var indices = GetEdgeIndicesForSegments(segments); // my "collector"
    // ... using the indices...
}
/// Compares the mid-points of each segment/edge to find the 
/// matching edge index. To speed up things, the indices for all
/// naked edges in the mesh has been collected prior to calling 
/// this method (see "te_indices")
private List<int> GetEdgeIndicesForSegments(Line[] segments, List<int> te_indices)
{
	var res_indices = new List<int>(segments.Length);
	for (int i = 0; i < segments.Length; i++)
	{
		var mid_line = segments[i].PointAt(0.5);
		// Now, find a matching topology edge INDEX (by comparing mid points)
		for (int j = 0; j < te_indices.Count; j++)
		{
			var edge = m_TE.EdgeLine(te_indices[j]);
			var mid_edge = edge.PointAt(0.5);
			if (mid_line.DistanceTo(mid_edge) < 0.001)
			{
			  res_indices.Add(te_indices[j]);
			  break; // --> next line in segments[i]
			}
		}
	}
	return res_indices;
}

By using cached indices for naked edges (ne_indices) in the matching algorithm, the total time for collecting grouped/ordered edge indices went from 47sec down to 350ms, which of course is better.

But, I will use the matched indices in an iteration for mesh cleaning (removing “tooth faces” etc) which typically runs 3 or 4 iterations to remove all unwanted crap, which means ~ 3 * 350ms (~ 1 sec altogether).

//Rolf

Hm, adding a “visited” array speeded it up significantly. The whole thing going from 1.2 sek down to 160 ms. New version:

  private List<int> GetEdgeIndicesForSegments(Line[] segments, List<int> te_indices)
  {   
    var visited = new bool[te_indices.Count]; // + "visited list" for speedup
    var res_indices = new List<int>(segments.Length);

    for (int i = 0; i < segments.Length; i++)
    {
      var mid_line = segments[i].PointAt(0.5);
      // Now, find a matching topology edge INDEX (by comparing mid points)
      for (int j = 0; j < te_indices.Count; j++)
      {
        if (visited[j]) continue; // speedup: 1200ms --> 160ms in total
        
        var edge = m_TE.EdgeLine(te_indices[j]);
        var mid_edge = edge.PointAt(0.5);
        if (mid_line.DistanceTo(mid_edge) < 0.01)
        {
          res_indices.Add(te_indices[j]);
          visited[j] = true;
          break;  // --> next line in segments[i]
        }
      }
    }
    return res_indices;
  }

More ideas?

//Rolf

image ,
image

I added a GetEdgeIndicesByFaceCount function to Rhino 8 this morning
int[] nakedEdgeIndices = mesh.Edges.GetEdgeIndicesByFaceCount(1);

Please let me know if this works for you.

OK, Ill try that. Must update R8 first…

Sounds good; I won’t roll this into Rhino 7 until we figure out if it will solve the problem.

A post was split to a new topic: Problems with GH script components in WIP