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