public boolean addAll(final long index, final FloatList l) { ensureIndex(index); to += l.size(); if (ASSERTS) { boolean retVal = this.l.addAll(from + index, l); assertRange(); return retVal; } return this.l.addAll(from + index, l); }
/** * Gets a contour surface for a specified image value. * * @param c the image value to contour. * @param withNormals true, for normal vectors; false, otherwise. */ public Contour getContour(float c) { IntList tlist = new IntList(); FloatList xlist = new FloatList(); FloatList ulist = _normals ? new FloatList() : null; march( _s1.getCount(), _s2.getCount(), _s3.getCount(), _s1.getDelta(), _s2.getDelta(), _s3.getDelta(), _s1.getFirst(), _s2.getFirst(), _s3.getFirst(), _f, c, tlist, xlist, ulist); Contour contour = new Contour(); contour.i = tlist.trim(); contour.x = xlist.trim(); contour.u = _normals ? ulist.trim() : null; if (_swap13) { float[] x = contour.x; float[] u = contour.u; for (int i = x.length - 3; i >= 0; i -= 3) { float x1 = x[i]; float x3 = x[i + 2]; x[i] = x3; x[i + 2] = x1; if (u != null) { float u1 = u[i]; float u3 = u[i + 2]; u[i] = u3; u[i + 2] = u1; } } } return contour; }
private static void march( int n1, int n2, int n3, double d1, double d2, double d3, double f1, double f2, double f3, float[][][] f, float c, IntList tlist, FloatList xlist, FloatList ulist) { float[] u = new float[3]; // Arrays of indices of vertices computed only once and stored in lists. // The two arrays ixa and ixb contain indices for one 2D slab of cubes. // A non-negative index in either array points to a computed vertex, and // a triangle is represented by three such indices. Here we initialize // all of the indices to -1, since no vertices have yet been computed. int[][][] ixa = new int[n2][n1][3]; int[][][] ixb = new int[n2][n1][3]; for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { for (int kk = 0; kk < 3; ++kk) { ixa[i2][i1][kk] = -1; ixb[i2][i1][kk] = -1; } } } // Numbers of vertices (and normal vectors) and triangle. int nx = 0; int nt = 0; // For all slabs of cubes, ... for (int i3 = 0; i3 < n3 - 1; ++i3) { // For all cubes in this slab, ... for (int i2 = 0; i2 < n2 - 1; ++i2) { for (int i1 = 0; i1 < n1 - 1; ++i1) { // Eight corner values for this cube. float c0 = f[i3][i2][i1]; float c1 = f[i3][i2][i1 + 1]; float c2 = f[i3][i2 + 1][i1 + 1]; float c3 = f[i3][i2 + 1][i1]; float c4 = f[i3 + 1][i2][i1]; float c5 = f[i3 + 1][i2][i1 + 1]; float c6 = f[i3 + 1][i2 + 1][i1 + 1]; float c7 = f[i3 + 1][i2 + 1][i1]; // Case index for this cube. int caseIndex = 0; if (c0 > c) caseIndex += 1; if (c1 > c) caseIndex += 2; if (c2 > c) caseIndex += 4; if (c3 > c) caseIndex += 8; if (c4 > c) caseIndex += 16; if (c5 > c) caseIndex += 32; if (c6 > c) caseIndex += 64; if (c7 > c) caseIndex += 128; // If at least one triangle for this case, ... if (caseIndex > 0 && caseIndex < 255) { // Edges intersected by contour. int[] edges = _edges[caseIndex]; int ne = edges.length; // For all triangles (triplets of edge intersections), ... for (int ie = 0; ie < ne; ie += 3) { // For each of three triangle vertices, ... for (int je = 0; je < 3; ++je) { // Decode edge j->k into sample indices of j and axis to k. int edge = edges[ie + je]; float cj, ck; int j1, j2, j3, kk; switch (edge) { case 0: // 0->1 cj = c0; ck = c1; j1 = i1; j2 = i2; j3 = i3; kk = 0; break; case 1: // 1->2 cj = c1; ck = c2; j1 = i1 + 1; j2 = i2; j3 = i3; kk = 1; break; case 2: // 3->2 cj = c3; ck = c2; j1 = i1; j2 = i2 + 1; j3 = i3; kk = 0; break; case 3: // 0->3 cj = c0; ck = c3; j1 = i1; j2 = i2; j3 = i3; kk = 1; break; case 4: // 4->5 cj = c4; ck = c5; j1 = i1; j2 = i2; j3 = i3 + 1; kk = 0; break; case 5: // 5->6 cj = c5; ck = c6; j1 = i1 + 1; j2 = i2; j3 = i3 + 1; kk = 1; break; case 6: // 7->6 cj = c7; ck = c6; j1 = i1; j2 = i2 + 1; j3 = i3 + 1; kk = 0; break; case 7: // 4->7 cj = c4; ck = c7; j1 = i1; j2 = i2; j3 = i3 + 1; kk = 1; break; case 8: // 0->4 cj = c0; ck = c4; j1 = i1; j2 = i2; j3 = i3; kk = 2; break; case 9: // 1->5 cj = c1; ck = c5; j1 = i1 + 1; j2 = i2; j3 = i3; kk = 2; break; case 10: // 3->7 cj = c3; ck = c7; j1 = i1; j2 = i2 + 1; j3 = i3; kk = 2; break; default: // 2->6 cj = c2; ck = c6; j1 = i1 + 1; j2 = i2 + 1; j3 = i3; kk = 2; } // Index of vertex, if already computed; or -1, if not yet. int[] ixjj = (j3 == i3) ? ixa[j2][j1] : ixb[j2][j1]; int ix = ixjj[kk]; // If vertex not yet computed, compute and store coordinates, // and optionally compute and store normal vector components. if (ix < 0) { int k1, k2, k3; double x1, x2, x3; float dx = (c - cj) / (ck - cj); switch (kk) { case 0: // edge aligned with axis 1 k1 = j1 + 1; k2 = j2; k3 = j3; x1 = f1 + d1 * (j1 + dx); x2 = f2 + d2 * (j2); x3 = f3 + d3 * (j3); break; case 1: // edge aligned with axis 2 k1 = j1; k2 = j2 + 1; k3 = j3; x1 = f1 + d1 * (j1); x2 = f2 + d2 * (j2 + dx); x3 = f3 + d3 * (j3); break; default: // edge aligned with axis 3 k1 = j1; k2 = j2; k3 = j3 + 1; x1 = f1 + d1 * (j1); x2 = f2 + d2 * (j2); x3 = f3 + d3 * (j3 + dx); } ix = ixjj[kk] = nx; xlist.add((float) x1); xlist.add((float) x2); xlist.add((float) x3); ++nx; if (ulist != null) { computeNormalVector(j1, j2, j3, k1, k2, k3, n1, n2, n3, d1, d2, d3, dx, f, u); ulist.add(u[0]); ulist.add(u[1]); ulist.add(u[2]); } } // Append index of vertex to triangle list. tlist.add(ix); } // Number of triangles. ++nt; } } } } // Swap the index arrays ixa and ixb, and re-initialize all ixb to -1. int[][][] ixt = ixa; ixa = ixb; ixb = ixt; for (int i2 = 0; i2 < n2; ++i2) { for (int i1 = 0; i1 < n1; ++i1) { for (int kk = 0; kk < 3; ++kk) { ixb[i2][i1][kk] = -1; } } } } }