
struct Edge {
  int tri, edge, next;
};
typedef struct Edge Edge;
Edge *dangling_edges;
int de_length, de_alloc;

static int
alloc_dangling_edge()
{
  if (de_length == de_alloc) {
    if (de_alloc == 0) {
      de_alloc = 64;
      dangling_edges = MALLOC(de_alloc * sizeof(Edge));
    } else {
      de_alloc *= 2;
      dangling_edges = REALLOC(dangling_edges, de_alloc * sizeof(Edge));
    }
  }
  return de_length++;
}
static int
add_dangling_edge(int tri, int edge)
{
  int num = alloc_dangling_edge();
  dangling_edges[num].tri = tri;
  dangling_edges[num].edge = edge;
  dangling_edges[num].next = -1;

  {
    Vertex *v1, *v2;
    int i, k;
    v1 = triangles[tri].v[edge];
    v2 = triangles[tri].v[(edge+1)%3];
    for (i = 0; i < triangles_length; i++) {
      if (i == tri) continue;
      for (k = 0; k < 3; k++) {
        if (v1 == triangles[i].v[k] && v2 == triangles[i].v[(k+1)%3]) {
          g_print("Symmetric edges found\n");
        }
        if (v1 == triangles[i].v[k] && v2 == triangles[i].v[(k+2)%3]) {
          g_print("Antisymmetric edges found\n");
        }
      }
    }
  }

  return num;
}
static void
clear_dangling_edges()
{
  de_length = 0;
}


int
adaptive_patch_mesh_old()
{
  int i, j, k, kk;
  int found[3];
  Vertex *t[3];

  g_print("  begin adaptive_patch_mesh\n");

  /* Search for edges which are only owned by one triangle, and put them in a list. */
  clear_dangling_edges();
  for (i = 0; i < triangles_length; i++) {
    found[0] = found[1] = found[2] = 0;
    for (j = 0; j < triangles_length; j++) {
      if (i == j) continue;
      for (k = 0; k < 3; k++) {
        for (kk = 0; kk < 3; kk++) {
          if (triangles[i].v[k] == triangles[j].v[kk]
              && triangles[i].v[(k+1)%3] == triangles[j].v[(kk+2)%3]) {
            found[k]++;
            if (triangles[i].v[(k+2)%3] == triangles[j].v[(kk+1)%3]) {
              g_print("mirror triangles %i %i\n", i, j);
              triangles[i].submeshes = 0x8000;
              triangles[j].submeshes = 0x8000;
            }
          }
        }
      }
      if (found[0] && found[1] && found[2]) break;
    }
    for (k = 0; k < 3; k++) {
      if (found[k] == 0) {
        add_dangling_edge(i, k);
        triangles[i].submeshes = 1 << 1;
#if 0
        triangles[i].v[k]->cr = 0.0;
        triangles[i].v[k]->cg = 0.0;
        triangles[i].v[k]->cb = 1.0;
#endif
      } else if (found[k] > 1) {
        g_print("Yikes, an edge has >2 tris on it!\n");
      }
    }
  }

  g_print("  end adaptive_patch_mesh stage 1: de_length = %i\n", de_length);

  /* Search for "loops" of dangling edges. */
  for (i = 0; i < de_length; i++) {
    for (j = 0; j < de_length; j++) {
      if (triangles[dangling_edges[i].tri].v[(dangling_edges[i].edge+1)%3] ==
          triangles[dangling_edges[j].tri].v[dangling_edges[j].edge]) {
        if (i == j) {
          g_print("Gaa!  Zero-length edge!\n");
        }
        dangling_edges[i].next = j;
        break;
      }
    }
    if (j == de_length) {
      g_print("Gaa!  Edge %i of triangle %i has no 'next' edge!\n",
              dangling_edges[i].edge, dangling_edges[i].tri);
    }
  }

  g_print("  end adaptive_patch_mesh stage 2\n");

  /* Patch over the loops. */
#if 0
  k = 0;
  for (i = 0; i < de_length; i++) {
    if (dangling_edges[i].next == -1) continue;
    k++;
    for (j = i; dangling_edges[j].next != i; j = dangling_edges[j].next) {
      g_print("    FOO %i %i %i\n", i, j, dangling_edges[j].next);
    }
  }
  g_print("loop count %i\n", k);
#elif 0
  for (i = 0; i < de_length; i++) {
    if (dangling_edges[i].next == -1) continue;
    t[0] = triangles[dangling_edges[i].tri].v[dangling_edges[i].edge];

    j = dangling_edges[i].next;
    while (dangling_edges[j].next != i) {
      t[2] = triangles[dangling_edges[j].tri].v[dangling_edges[j].edge];
      k = dangling_edges[j].next;
      if (k == -1) {
        g_print("Gaa!  Gaa!  Gaa!\n");
        break;
      }
      dangling_edges[j].next = -1;
      j = k;
      t[1] = triangles[dangling_edges[j].tri].v[dangling_edges[j].edge];
      add_triangle(t);
    }
  }
#elif 0
  for (i = 0; i < de_length; i++) {
    if (dangling_edges[i].next == -1) continue;
    t[0] = triangles[dangling_edges[i].tri].v[dangling_edges[i].edge];
    for (j = dangling_edges[i].next;
         dangling_edges[j].next != i;
         j = dangling_edges[j].next) {
      if (j == -1) {
        g_print("Gaa!  Unterminated loop!\n");
        break;
      }
      t[1] = triangles[dangling_edges[j].tri].v[dangling_edges[j].edge];
      t[2] = triangles[dangling_edges[j].tri].v[(dangling_edges[j].edge+1)%3];
      add_triangle(t);
    }
  }
#endif

  g_print("  end adaptive_patch_mesh\n");
  return 0;
}
