Find Neighbors on each face of Mesh

Hi Everyone,
I am trying to detect which faces have a neighbor and which faces don’t in this exercise.
I have been able to achieve the number of neighbors for any selected module here.

What should be the next steps to sort the available neighbors for each boxes by their face index?
Any help will be appreciated.
Here is the Code snippet

using System;
using System.Collections;
using System.Collections.Generic;

using Rhino;
using Rhino.Geometry;

using Grasshopper;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;

using Rhino.Geometry.Intersect;
using System.Drawing;

/// <summary>
/// This class will be instantiated on demand by the Script component.
/// </summary>
public class Script_Instance : GH_ScriptInstance
{
#region Utility functions
  /// <summary>Print a String to the [Out] Parameter of the Script component.</summary>
  /// <param name="text">String to print.</param>
  private void Print(string text) { /* Implementation hidden. */ }
  /// <summary>Print a formatted String to the [Out] Parameter of the Script component.</summary>
  /// <param name="format">String format.</param>
  /// <param name="args">Formatting parameters.</param>
  private void Print(string format, params object[] args) { /* Implementation hidden. */ }
  /// <summary>Print useful information about an object instance to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj) { /* Implementation hidden. */ }
  /// <summary>Print the signatures of all the overloads of a specific method to the [Out] Parameter of the Script component. </summary>
  /// <param name="obj">Object instance to parse.</param>
  private void Reflect(object obj, string method_name) { /* Implementation hidden. */ }
#endregion

#region Members
  /// <summary>Gets the current Rhino document.</summary>
  private readonly RhinoDoc RhinoDocument;
  /// <summary>Gets the Grasshopper document that owns this script.</summary>
  private readonly GH_Document GrasshopperDocument;
  /// <summary>Gets the Grasshopper script component that owns this script.</summary>
  private readonly IGH_Component Component;
  /// <summary>
  /// Gets the current iteration count. The first call to RunScript() is associated with Iteration==0.
  /// Any subsequent call within the same solution will increment the Iteration count.
  /// </summary>
  private readonly int Iteration;
#endregion

  /// <summary>
  /// This procedure contains the user code. Input parameters are provided as regular arguments,
  /// Output parameters as ref arguments. You don't have to assign output parameters,
  /// they will have a default value.
  /// </summary>
  private void RunScript(List<Mesh> legoList, int selLego, ref object Selection, ref object Neighbors, ref object NeighborsInfo)
  {

    var neighborsDictionary = NeighborDetection(legoList);
    NeighborsInfo = NeighborInfo(neighborsDictionary);
    Selection = legoList[selLego];
    Neighbors = NeighborMeshes(legoList, selLego);


  }

  // <Custom additional code> 


  private List<Mesh> NeighborMeshes(List<Mesh> meshList, int selMod)
  {
    List<Mesh> neighborMeshes = new List<Mesh>();

    try
    {
      MeshClash[] meshClashArray = MeshClash.Search(meshList[selMod], meshList, 1500, 10);

      int[] neighIndices = new int[meshClashArray.Length];
      for(int index = 0; index < meshClashArray.Length; ++index)
      {
        neighIndices[index] = meshList.IndexOf(meshClashArray[index].MeshB);
      }

      foreach(var index in neighIndices)
      {
        if(index == selMod) continue;

        neighborMeshes.Add(meshList[index]);
      }
    }
    catch(Exception e)
    {
      Print(e.ToString());
    }


    return neighborMeshes;



  }

  private Dictionary<int, List<int>> NeighborDetection(List<Mesh> meshList)
  {
    Dictionary<int, List<int>> neighbors = new Dictionary<int, List<int>>();

    for(int i = 0; i < meshList.Count; i++)
    {
      try
      {
        MeshClash[] meshClashArray = MeshClash.Search(meshList[i], meshList, 1500, 10);
        int[] neighIndices = new int[meshClashArray.Length];
        for(int index = 0; index < meshClashArray.Length; ++index)
        {
          neighIndices[index] = meshList.IndexOf(meshClashArray[index].MeshB);
        }

        List<int> neighborsID = new List<int>();

        foreach(var index in neighIndices)
        {
          if(index == i) continue;
          neighborsID.Add(index);
        }
        neighbors.Add(i, neighborsID);
      }
      catch(Exception e)
      {
        Print(e.ToString());
      }
    }

    return neighbors;
  }

  private List<string> NeighborInfo(Dictionary<int, List<int>> neighbors)
  {
    List<string> neighborsInfo = new List<string>();

    foreach(var legoInfo in neighbors.Keys)
    {
      neighborsInfo.Add("LegoID: " + legoInfo.ToString());
      foreach(var neighIDs in neighbors[legoInfo])
      {
        neighborsInfo.Add(neighIDs.ToString());
      }
    }
    return neighborsInfo;

  }


  // </Custom additional code> 
}

Find_neighbor_on_each_face.gh (8.5 KB)

@PeterFotiadis , could Lord of Darkness shed some light on it?

Get some then: as an indicative start (Plus a challenge for the brave [1st prize: DaMorgada sardines in pure W15/40 mineral oil]):

Mesh_connectivityTrees_Public_V1A.gh (217.6 KB)

PS: What means “sort”? You mean a FF conn thingy?

This is computational geometry and there’s a systematic way of achieving this.

For triangle mesh, you can check my plugin IG-Mesh (GitHub - xarthurx/IG-Mesh: An one-stop solution for mesh processing in Grasshopper (for Rhino)).
Or check the source code of libigl library.