void make_connectivity_graph(graph_array<triangle> & Triangles, const indices & Indices)
{
    assert(Triangles.size() == (Indices.size() / 3));

    // Fill the triangle data
    for (size_t i = 0; i < Triangles.size(); ++i)
        Triangles[i] = triangle(Indices[i * 3 + 0], Indices[i * 3 + 1], Indices[i * 3 + 2]);

    // Build an edge lookup table
    edge_map EdgeMap;
    EdgeMap.reserve(Triangles.size() * 3);

    for (size_t i = 0; i < Triangles.size(); ++i) {

        const triangle & Tri = * Triangles[i];

        EdgeMap.push_back(tri_edge(Tri.A(), Tri.B(), i)); 
        EdgeMap.push_back(tri_edge(Tri.B(), Tri.C(), i)); 
        EdgeMap.push_back(tri_edge(Tri.C(), Tri.A(), i)); 
    }

    std::sort(EdgeMap.begin(), EdgeMap.end(), cmp_tri_edge_lt());

    // Link neighbour triangles together using the lookup table
    for (size_t i = 0; i < Triangles.size(); ++i) {

        const triangle & Tri = * Triangles[i];

        LinkNeighbours(Triangles, EdgeMap, tri_edge(Tri.B(), Tri.A(), i)); 
        LinkNeighbours(Triangles, EdgeMap, tri_edge(Tri.C(), Tri.B(), i)); 
        LinkNeighbours(Triangles, EdgeMap, tri_edge(Tri.A(), Tri.C(), i)); 
    }
}
tri_stripper::tri_stripper(const indices & TriIndices)
	: m_Triangles(TriIndices.size() / 3), // Silently ignore extra indices if (Indices.size() % 3 != 0)
	  m_StripID(0),
	  m_FirstRun(true)
{
	SetCacheSize();
	SetMinStripSize();
	SetBackwardSearch();
	SetPushCacheHits();

	make_connectivity_graph(m_Triangles, TriIndices);
}