static int TetsurfFindActiveBoxes()

in layer0/Tetsurf.cpp [759:1495]


static int TetsurfFindActiveBoxes(CTetsurf * II, int mode, int *n_strip, int n_vert,
                                  int **strip_l, float **vert,
                                  MapType * voxelmap, float *a_vert,
                                  float carvebuffer, int side)
{
  CTetsurf *I = II;
  int a, b, c, i, j, k, h, l;
#ifdef Trace
  int ECount = 0;
#endif
  int i000, i001, i010, i011, i100, i101, i110, i111;
  float *c000, *c001, *c010, *c011, *c100, *c101, *c110, *c111;
  float d000, d001, d010, d011, d100, d101, d110, d111;
  float *g000 = NULL, *g001 = NULL, *g010 = NULL, *g011 = NULL, *g100 = NULL, *g101 =
    NULL, *g110 = NULL, *g111 = NULL;

  int active;
  int n_active = 0;
  int n_start = 0;
  PointType *e[19], *p0, *p1, *p2;
  int code;
  int eidx;
  int idx;
  TriangleType *tt;
  int n_tri = 0;
  int n_link = 1;

  int avoid_flag = false;
  if(carvebuffer < 0.0F) {
    avoid_flag = true;
    carvebuffer = -carvebuffer;
  }

  FieldZero(I->Point);          /* sets initial links to zero */
  FieldZero(I->ActiveEdges);
  n_start = n_vert;
  for(i = 0; i < (I->Max[0] - 1); i++)
    for(j = 0; j < (I->Max[1] - 1); j++)
      for(k = 0; k < (I->Max[2] - 1); k++) {
        active = 0;

        i000 = I3(I->VertexCodes, i, j, k);
        i001 = I3(I->VertexCodes, i, j, k + 1);
        i010 = I3(I->VertexCodes, i, j + 1, k);
        i011 = I3(I->VertexCodes, i, j + 1, k + 1);
        i100 = I3(I->VertexCodes, i + 1, j, k);
        i101 = I3(I->VertexCodes, i + 1, j, k + 1);
        i110 = I3(I->VertexCodes, i + 1, j + 1, k);
        i111 = I3(I->VertexCodes, i + 1, j + 1, k + 1);

        if((i000 != i001) || (i001 != i010) || (i010 != i011) || (i011 != i100) || (i100 != i101) || (i101 != i110) || (i110 != i111)) {        /* this is an active box */

          c000 = O4Ptr(I->Coord, i, j, k, 0, I->CurOff);
          c001 = O4Ptr(I->Coord, i, j, k + 1, 0, I->CurOff);
          c010 = O4Ptr(I->Coord, i, j + 1, k, 0, I->CurOff);
          c011 = O4Ptr(I->Coord, i, j + 1, k + 1, 0, I->CurOff);
          c100 = O4Ptr(I->Coord, i + 1, j, k, 0, I->CurOff);
          c101 = O4Ptr(I->Coord, i + 1, j, k + 1, 0, I->CurOff);
          c110 = O4Ptr(I->Coord, i + 1, j + 1, k, 0, I->CurOff);
          c111 = O4Ptr(I->Coord, i + 1, j + 1, k + 1, 0, I->CurOff);

          if(mode == 3) {

            g000 = O4Ptr(I->Grad, i, j, k, 0, I->CurOff);
            g001 = O4Ptr(I->Grad, i, j, k + 1, 0, I->CurOff);
            g010 = O4Ptr(I->Grad, i, j + 1, k, 0, I->CurOff);
            g011 = O4Ptr(I->Grad, i, j + 1, k + 1, 0, I->CurOff);
            g100 = O4Ptr(I->Grad, i + 1, j, k, 0, I->CurOff);
            g101 = O4Ptr(I->Grad, i + 1, j, k + 1, 0, I->CurOff);
            g110 = O4Ptr(I->Grad, i + 1, j + 1, k, 0, I->CurOff);
            g111 = O4Ptr(I->Grad, i + 1, j + 1, k + 1, 0, I->CurOff);
          }

          d000 = O3(I->Data, i, j, k, I->CurOff);
          d001 = O3(I->Data, i, j, k + 1, I->CurOff);
          d010 = O3(I->Data, i, j + 1, k, I->CurOff);
          d011 = O3(I->Data, i, j + 1, k + 1, I->CurOff);
          d100 = O3(I->Data, i + 1, j, k, I->CurOff);
          d101 = O3(I->Data, i + 1, j, k + 1, I->CurOff);
          d110 = O3(I->Data, i + 1, j + 1, k, I->CurOff);
          d111 = O3(I->Data, i + 1, j + 1, k + 1, I->CurOff);

          e[cE_000_001] = EdgePtPtr(I->Point, i, j, k, cE_000_001);
          e[cE_000_010] = EdgePtPtr(I->Point, i, j, k, cE_000_010);
          e[cE_000_011] = EdgePtPtr(I->Point, i, j, k, cE_000_011);
          e[cE_000_100] = EdgePtPtr(I->Point, i, j, k, cE_000_100);
          e[cE_000_101] = EdgePtPtr(I->Point, i, j, k, cE_000_101);

          e[cE_000_110] = EdgePtPtr(I->Point, i, j, k, cE_000_110);
          e[cE_000_111] = EdgePtPtr(I->Point, i, j, k, cE_000_111);
          e[cE_001_011] = EdgePtPtr(I->Point, i, j, k + 1, cE_000_010);
          e[cE_001_101] = EdgePtPtr(I->Point, i, j, k + 1, cE_000_100);
          e[cE_001_111] = EdgePtPtr(I->Point, i, j, k + 1, cE_000_110);

          e[cE_010_011] = EdgePtPtr(I->Point, i, j + 1, k, cE_000_001);
          e[cE_010_110] = EdgePtPtr(I->Point, i, j + 1, k, cE_000_100);
          e[cE_010_111] = EdgePtPtr(I->Point, i, j + 1, k, cE_000_101);
          e[cE_100_101] = EdgePtPtr(I->Point, i + 1, j, k, cE_000_001);
          e[cE_100_110] = EdgePtPtr(I->Point, i + 1, j, k, cE_000_010);

          e[cE_100_111] = EdgePtPtr(I->Point, i + 1, j, k, cE_000_011);
          e[cE_011_111] = EdgePtPtr(I->Point, i, j + 1, k + 1, cE_000_100);
          e[cE_101_111] = EdgePtPtr(I->Point, i + 1, j, k + 1, cE_000_010);
          e[cE_110_111] = EdgePtPtr(I->Point, i + 1, j + 1, k, cE_000_001);

          /* Generate interpolated coordinates for all active edges */

          if(i000 != i001) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_001)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_001;
              TetsurfInterpolate2(e[cE_000_001]->Point, c000, d000, c001, d001, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_000_001]->Normal, g000, d000, g001, d001,
                                    I->Level);
            }
            active |= cM_000_001;
          }
          if(i000 != i010) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_010)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_010;
              TetsurfInterpolate2(e[cE_000_010]->Point, c000, d000, c010, d010, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_000_010]->Normal, g000, d000, g010, d010,
                                    I->Level);

            }
            active |= cM_000_010;
          }
          if(i000 != i011) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_011)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_011;
              TetsurfInterpolate4(e[cE_000_011]->Point, c000, d000, c011, d011, d001,
                                  d010, I->Level);
              if(mode == 3)
                TetsurfInterpolate4(e[cE_000_011]->Normal, g000, d000, g011, d011, d001,
                                    d010, I->Level);
            }
            active |= cM_000_011;
          }
          if(i000 != i100) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_100)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_100;
              TetsurfInterpolate2(e[cE_000_100]->Point, c000, d000, c100, d100, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_000_100]->Normal, g000, d000, g100, d100,
                                    I->Level);

            }
            active |= cM_000_100;
          }
          if(i000 != i101) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_101)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_101;
              TetsurfInterpolate4(e[cE_000_101]->Point, c000, d000, c101, d101, d100,
                                  d001, I->Level);
              if(mode == 3)
                TetsurfInterpolate4(e[cE_000_101]->Normal, g000, d000, g101, d101, d100,
                                    d001, I->Level);
            }
            active |= cM_000_101;
          }
          if(i000 != i110) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_110)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_110;
              TetsurfInterpolate4(e[cE_000_110]->Point, c000, d000, c110, d110, d100,
                                  d010, I->Level);
              if(mode == 3)
                TetsurfInterpolate4(e[cE_000_110]->Normal, g000, d000, g110, d110, d100,
                                    d010, I->Level);
            }
            active |= cM_000_110;
          }
          if(i000 != i111) {
            if(!(I3(I->ActiveEdges, i, j, k) & cM_000_111)) {
              I3(I->ActiveEdges, i, j, k) |= cM_000_111;
              TetsurfInterpolate8(e[cE_000_111]->Point,
                                  c000, d000, c111, d111,
                                  d001, d010, d011, d100, d101, d110, I->Level);
              if(mode == 3)
                TetsurfInterpolate8(e[cE_000_111]->Normal,
                                    g000, d000, g111, d111,
                                    d001, d010, d011, d100, d101, d110, I->Level);
            }
            active |= cM_000_111;
          }
          if(i001 != i011) {
            if(!(I3(I->ActiveEdges, i, j, k + 1) & cM_000_010)) {
              I3(I->ActiveEdges, i, j, k + 1) |= cM_000_010;
              TetsurfInterpolate2(e[cE_001_011]->Point, c001, d001, c011, d011, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_001_011]->Normal, g001, d001, g011, d011,
                                    I->Level);
            }
            active |= cM_001_011;
          }
          if(i001 != i101) {
            if(!(I3(I->ActiveEdges, i, j, k + 1) & cM_000_100)) {
              I3(I->ActiveEdges, i, j, k + 1) |= cM_000_100;
              TetsurfInterpolate2(e[cE_001_101]->Point, c001, d001, c101, d101, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_001_101]->Normal, g001, d001, g101, d101,
                                    I->Level);
            }
            active |= cM_001_101;
          }
          if(i001 != i111) {
            if(!(I3(I->ActiveEdges, i, j, k + 1) & cM_000_110)) {
              I3(I->ActiveEdges, i, j, k + 1) |= cM_000_110;
              TetsurfInterpolate4(e[cE_001_111]->Point, c001, d001, c111, d111, d101,
                                  d011, I->Level);
              if(mode == 3)
                TetsurfInterpolate4(e[cE_001_111]->Normal, g001, d001, g111, d111, d101,
                                    d011, I->Level);
            }
            active |= cM_001_111;
          }
          if(i010 != i011) {
            if(!(I3(I->ActiveEdges, i, j + 1, k) & cM_000_001)) {
              I3(I->ActiveEdges, i, j + 1, k) |= cM_000_001;
              TetsurfInterpolate2(e[cE_010_011]->Point, c010, d010, c011, d011, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_010_011]->Normal, g010, d010, g011, d011,
                                    I->Level);
            }
            active |= cM_010_011;
          }
          if(i010 != i110) {
            if(!(I3(I->ActiveEdges, i, j + 1, k) & cM_000_100)) {
              I3(I->ActiveEdges, i, j + 1, k) |= cM_000_100;
              TetsurfInterpolate2(e[cE_010_110]->Point, c010, d010, c110, d110, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_010_110]->Normal, g010, d010, g110, d110,
                                    I->Level);
            }
            active |= cM_010_110;
          }
          if(i010 != i111) {
            if(!(I3(I->ActiveEdges, i, j + 1, k) & cM_000_101)) {
              I3(I->ActiveEdges, i, j + 1, k) |= cM_000_101;
              TetsurfInterpolate4(e[cE_010_111]->Point, c010, d010, c111, d111, d110,
                                  d011, I->Level);
              if(mode == 3)
                TetsurfInterpolate4(e[cE_010_111]->Normal, g010, d010, g111, d111, d110,
                                    d011, I->Level);
            }
            active |= cM_010_111;
          }
          if(i100 != i101) {
            if(!(I3(I->ActiveEdges, i + 1, j, k) & cM_000_001)) {
              I3(I->ActiveEdges, i + 1, j, k) |= cM_000_001;
              TetsurfInterpolate2(e[cE_100_101]->Point, c100, d100, c101, d101, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_100_101]->Normal, g100, d100, g101, d101,
                                    I->Level);
            }
            active |= cM_100_101;
          }
          if(i100 != i110) {
            if(!(I3(I->ActiveEdges, i + 1, j, k) & cM_000_010)) {
              I3(I->ActiveEdges, i + 1, j, k) |= cM_000_010;
              TetsurfInterpolate2(e[cE_100_110]->Point, c100, d100, c110, d110, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_100_110]->Normal, g100, d100, g110, d110,
                                    I->Level);
            }
            active |= cM_100_110;
          }
          if(i100 != i111) {
            if(!(I3(I->ActiveEdges, i + 1, j, k) & cM_000_011)) {
              I3(I->ActiveEdges, i + 1, j, k) |= cM_000_011;
              TetsurfInterpolate4(e[cE_100_111]->Point, c100, d100, c111, d111, d101,
                                  d110, I->Level);
              if(mode == 3)
                TetsurfInterpolate4(e[cE_100_111]->Normal, g100, d100, g111, d111, d101,
                                    d110, I->Level);
            }
            active |= cM_100_111;
          }
          if(i011 != i111) {
            if(!(I3(I->ActiveEdges, i, j + 1, k + 1) & cM_000_100)) {
              I3(I->ActiveEdges, i, j + 1, k + 1) |= cM_000_100;
              TetsurfInterpolate2(e[cE_011_111]->Point, c011, d011, c111, d111, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_011_111]->Normal, g011, d011, g111, d111,
                                    I->Level);
            }
            active |= cM_011_111;
          }
          if(i101 != i111) {
            if(!(I3(I->ActiveEdges, i + 1, j, k + 1) & cM_000_010)) {
              I3(I->ActiveEdges, i + 1, j, k + 1) |= cM_000_010;
              TetsurfInterpolate2(e[cE_101_111]->Point, c101, d101, c111, d111, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_101_111]->Normal, g101, d101, g111, d111,
                                    I->Level);
            }
            active |= cM_101_111;
          }
          if(i110 != i111) {
            if(!(I3(I->ActiveEdges, i + 1, j + 1, k) & cM_000_001)) {
              I3(I->ActiveEdges, i + 1, j + 1, k) |= cM_000_001;
              TetsurfInterpolate2(e[cE_110_111]->Point, c110, d110, c111, d111, I->Level);
              if(mode == 3)
                TetsurfInterpolate2(e[cE_110_111]->Normal, g110, d110, g111, d111,
                                    I->Level);
            }
            active |= cM_110_111;
          }

          if(active) {
            switch (mode) {
            case 2:
            case 3:
              code =
                (i000 ? 0x01 : 0) |
                (i001 ? 0x02 : 0) |
                (i010 ? 0x04 : 0) |
                (i011 ? 0x08 : 0) |
                (i100 ? 0x10 : 0) |
                (i101 ? 0x20 : 0) | (i110 ? 0x40 : 0) | (i111 ? 0x80 : 0);
              eidx = I->EdgeStart[code];
              while(1) {
                idx = I->Edge[eidx];
                if(idx < 0)
                  break;

                /* assemble a triangle from these three points */

                VLACheck(I->Tri, TriangleType, n_tri);
                tt = I->Tri + n_tri;
                tt->p[0] = e[idx];
                tt->p[1] = e[I->Edge[eidx + 1]];
                tt->p[2] = e[I->Edge[eidx + 2]];

                VLACheck(I->PtLink, PointLinkType, n_link + 3);

                /* link this triangle into the points */

                I->PtLink[n_link].tri = n_tri;
                I->PtLink[n_link].link = tt->p[0]->Link;
                tt->p[0]->Link = n_link;
                n_link++;

                I->PtLink[n_link].tri = n_tri;
                I->PtLink[n_link].link = tt->p[1]->Link;
                tt->p[1]->Link = n_link;
                n_link++;

                I->PtLink[n_link].tri = n_tri;
                I->PtLink[n_link].link = tt->p[2]->Link;
                tt->p[2]->Link = n_link;
                n_link++;
                n_tri++;
                eidx += 3;
              }
              break;
            case 1:            /* lines */
              VLACheck(*vert, float, (n_vert * 3) + 200);

              code =
                (i000 ? 0x01 : 0) |
                (i001 ? 0x02 : 0) |
                (i010 ? 0x04 : 0) |
                (i011 ? 0x08 : 0) |
                (i100 ? 0x10 : 0) |
                (i101 ? 0x20 : 0) | (i110 ? 0x40 : 0) | (i111 ? 0x80 : 0);
              eidx = I->EdgeStart[code];
              while(1) {
                idx = I->Edge[eidx];
                if(idx < 0)
                  break;
                copy3fn(e[idx]->Point, (*vert) + (n_vert * 3));
                n_vert++;
                copy3fn(e[I->Edge[eidx + 1]]->Point, (*vert) + (n_vert * 3));
                n_vert++;
                copy3fn(e[I->Edge[eidx + 1]]->Point, (*vert) + (n_vert * 3));
                n_vert++;
                copy3fn(e[I->Edge[eidx + 2]]->Point, (*vert) + (n_vert * 3));
                n_vert++;
                copy3fn(e[I->Edge[eidx + 2]]->Point, (*vert) + (n_vert * 3));
                n_vert++;
                copy3fn(e[idx]->Point, (*vert) + (n_vert * 3));
                n_vert++;
                eidx += 3;
              }
              break;
            case 0:
            default:           /* dots */
              VLACheck(*vert, float, (n_vert * 3) + 200);

              if(active & cM_000_001) {
                copy3fn(e[cE_000_001]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_000_010) {
                copy3fn(e[cE_000_010]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_000_011) {
                copy3fn(e[cE_000_011]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_000_100) {
                copy3fn(e[cE_000_100]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_000_101) {
                copy3fn(e[cE_000_101]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_000_110) {
                copy3fn(e[cE_000_110]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_000_111) {
                copy3fn(e[cE_000_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }

              if(active & cM_001_011) {
                copy3fn(e[cE_001_011]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_001_101) {
                copy3fn(e[cE_001_101]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_001_111) {
                copy3fn(e[cE_001_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }

              if(active & cM_010_011) {
                copy3fn(e[cE_010_011]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_010_110) {
                copy3fn(e[cE_010_011]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_010_111) {
                copy3fn(e[cE_010_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }

              if(active & cM_100_101) {
                copy3fn(e[cE_100_101]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_100_110) {
                copy3fn(e[cE_100_110]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_100_111) {
                copy3fn(e[cE_100_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }

              if(active & cM_011_111) {
                copy3fn(e[cE_011_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_101_111) {
                copy3fn(e[cE_101_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }
              if(active & cM_110_111) {
                copy3fn(e[cE_101_111]->Point, (*vert) + (n_vert * 3));
                n_vert += 1;
              }

              break;
            }
            n_active++;
          }
        }
      }

  switch (mode) {
  case 2:
  case 3:
    /* compute area-weighted normal */
    for(a = 0; a < n_tri; a++) {
      float *v0, *v1, *v2;
      float vt1[3], vt2[3];

      tt = I->Tri + a;
      v0 = tt->p[0]->Point;
      v1 = tt->p[1]->Point;
      v2 = tt->p[2]->Point;
      tt->done = false;         /* init */

      subtract3f(v0, v2, vt1);
      subtract3f(v1, v2, vt2);
      if(side >= 0) {
        cross_product3f(vt2, vt1, tt->n);
      } else {
        cross_product3f(vt1, vt2, tt->n);
      }
    }
    /* compute (or lookup) normals at active points */
    for(a = 0; a < n_tri; a++) {
      float v[3];
      float dp;
      tt = I->Tri + a;
      for(b = 0; b < 3; b++) {
        if(!tt->p[b]->NormalFlag) {
          zero3f(v);
          idx = tt->p[b]->Link;
          while(idx > 0) {
            add3f(I->Tri[I->PtLink[idx].tri].n, v, v);
            idx = I->PtLink[idx].link;
          }
          if(mode == 3) {       /* gradient-based normals */
            dp = dot_product3f(v, tt->p[b]->Normal);
            if(dp < 0.0F) {
              invert3f(tt->p[b]->Normal);
              normalize3f(tt->p[b]->Normal);
            } else if(dp == 0.0F) {     /* fall back on triangle normal */
              normalize23f(v, tt->p[b]->Normal);
            } else {
              normalize3f(tt->p[b]->Normal);
            }
          } else {              /* triangle-based normals */
            normalize23f(v, tt->p[b]->Normal);
          }
          tt->p[b]->NormalFlag = true;
        }
      }
    }
    if(mode == 2) {
      /* if we're using triangle normals, then 
         do an additional averaging cycle with no weighting */
      for(a = 0; a < n_tri; a++) {
        tt = I->Tri + a;
        add3f(tt->p[0]->Normal, tt->p[1]->Normal, tt->n);
        add3f(tt->p[2]->Normal, tt->n, tt->n);
        normalize3f(tt->n);
        tt->p[0]->NormalFlag = false;
        tt->p[1]->NormalFlag = false;
        tt->p[2]->NormalFlag = false;
      }
      /* compute normals at active points */
      for(a = 0; a < n_tri; a++) {
        float v[3];
        tt = I->Tri + a;
        for(b = 0; b < 3; b++) {
          if(!tt->p[b]->NormalFlag) {
            zero3f(v);
            idx = tt->p[b]->Link;
            while(idx > 0) {
              add3f(I->Tri[I->PtLink[idx].tri].n, v, v);
              idx = I->PtLink[idx].link;
            }
            normalize23f(v, tt->p[b]->Normal);
            tt->p[b]->NormalFlag = true;
          }
        }
      }
    }

    /* Need to move the points now, right? */

    /* if we are carving, then exclude triangles outside region */
    if(voxelmap) {
      for(a = 0; a < n_tri; a++) {
        float *v;
        tt = I->Tri + a;
        c = 0;
        for(b = 0; b < 3; b++) {
          v = tt->p[b]->Point;
          MapLocus(voxelmap, v, &h, &k, &l);
          i = *(MapEStart(voxelmap, h, k, l));
          if(i) {
            j = voxelmap->EList[i++];
            while(j >= 0) {
              if(within3f(a_vert + 3 * j, v, carvebuffer)) {
                c++;
                break;
              }
              j = voxelmap->EList[i++];
            }
          }
        }
        if(avoid_flag) {
          if(c >= 3)
            tt->done = true;    /* exclude this triangle from the surface */
        } else {
          if(c < 3)             /* exclude this triangle from the surface */
            tt->done = true;
        }
      }
    }

    /* now create triangle strips (not yet optimal) */
    for(a = 0; a < n_tri; a++) {
      tt = I->Tri + a;
      n_start = n_vert;
      if(!tt->done) {

        VLACheck(*vert, float, (n_vert * 3) + 200);

        if(side >= 0) {
          /* switch order around to get "correct" triangles */

          copy3fn(tt->p[1]->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(tt->p[1]->Point, (*vert) + (n_vert * 3));
          n_vert++;

          copy3fn(tt->p[0]->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(tt->p[0]->Point, (*vert) + (n_vert * 3));
          n_vert++;

          copy3fn(tt->p[2]->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(tt->p[2]->Point, (*vert) + (n_vert * 3));
          n_vert++;

          p0 = tt->p[0];
          p1 = tt->p[2];

        } else {

          copy3fn(tt->p[0]->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(tt->p[0]->Point, (*vert) + (n_vert * 3));
          n_vert++;

          copy3fn(tt->p[1]->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(tt->p[1]->Point, (*vert) + (n_vert * 3));
          n_vert++;

          copy3fn(tt->p[2]->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(tt->p[2]->Point, (*vert) + (n_vert * 3));
          n_vert++;

          p0 = tt->p[1];
          p1 = tt->p[2];

        }

        tt->done = true;

        while(1) {
          p2 = NULL;
          idx = p1->Link;
          while(idx > 0) {
            tt = I->Tri + I->PtLink[idx].tri;

            if(!tt->done) {
              if((tt->p[0] == p0) && (tt->p[1] == p1)) {
                p2 = tt->p[2];
                break;
              }

              if((tt->p[1] == p0) && (tt->p[2] == p1)) {
                p2 = tt->p[0];
                break;
              }

              if((tt->p[2] == p0) && (tt->p[0] == p1)) {
                p2 = tt->p[1];
                break;
              }

              if((tt->p[1] == p0) && (tt->p[0] == p1)) {
                p2 = tt->p[2];
                break;
              }

              if((tt->p[2] == p0) && (tt->p[1] == p1)) {
                p2 = tt->p[0];
                break;
              }

              if((tt->p[0] == p0) && (tt->p[2] == p1)) {
                p2 = tt->p[1];
                break;
              }
            }
            idx = I->PtLink[idx].link;
          }

          if(!p2)
            break;
          tt->done = true;
          VLACheck(*vert, float, (n_vert * 3) + 200);
          copy3fn(p2->Normal, (*vert) + (n_vert * 3));
          n_vert++;
          copy3fn(p2->Point, (*vert) + (n_vert * 3));
          n_vert++;
          p0 = p1;
          p1 = p2;
        }
      }
      if(n_vert > n_start) {
        VLACheck(*strip_l, int, *n_strip);
        (*strip_l)[*n_strip] = n_vert - n_start;
        (*n_strip)++;
      }
    }
    I->TotPrim += n_tri;
    break;

  case 1:
    /* Need to move the points now, right? */

    if(n_vert > n_start) {
      VLACheck(*strip_l, int, *n_strip);
      (*strip_l)[*n_strip] = n_vert - n_start;
      (*n_strip)++;
    }
    break;
  case 0:                      /* dots */
  default:

    /* Need to move the points now, right? */

    if(n_vert > n_start) {
      VLACheck(*strip_l, int, *n_strip);
      (*strip_l)[*n_strip] = n_vert - n_start;
      (*n_strip)++;
    }
    break;
  }
  /*
     printf("n_strip %d\n",*n_strip);
     printf("n_active %d\n",n_active);
     printf("n_vert %d\n",n_vert);
     printf("mode %d\n",mode);
   */
  return (n_vert);
}