// Decompiled by Jad v1.5.7b. Copyright 1997-99 Pavel Kouznetsov. // Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html // Decompiler options: packimports(3) // Source File Name: ImplicitTiler.java import java.io.PrintStream; import java.util.Vector; import java.util.Iterator; import java.util.PriorityQueue; class ImplicitTiler implements Simplex.Solid { // Simplex.Solid public boolean inside(double x, double y, double z) { return implicit.inside(x, y, z, false); // true); } public void push(Simplex simplex) { //assert (!simplexStack.contains(simplex)); //assert (!simplex.postpone); { //System.out.println("Remove = " + simplex); //simplexStack.remove(simplex); //} //System.out.println("Push = " + simplex); simplexStack.offer(simplex); } } static public void DumpStack() { Iterator inter = simplexStack.iterator(); while (inter.hasNext()) { Simplex si = (Simplex) inter.next(); System.out.println("stack contains " + si); } } public void push(Vector simplex) { for (int i = 0; i < simplex.size(); i++) { push((Simplex) simplex.get(i)); } } public int MinDepth() { return (int) cellSize; } public int MaxDepth() { return (int) cellSize2; } public double Tolerance() { return 0; // tolerance; } //boolean DEBUG = true; // false; boolean DEBUG = false; double x[] = new double[2]; double y[] = new double[2]; double z[] = new double[2]; static int SURFACEID = 0; static int VOLUMEID = 1; static int INNERID = 2; static int OUTERID = 3; static int BOUNDARYID = 4; ImplicitTiler(Object3D imp, int genType, boolean genNormals, boolean trim, boolean stripify, double size, double size2, double tol, boolean interval) { if (genType == SURFACEID) { Simplex.SURFACE = true; Simplex.SOLID = false; Simplex.BOUNDARY = false; } if (genType == VOLUMEID) { Simplex.SURFACE = true; Simplex.SOLID = true; Simplex.BOUNDARY = false; } if (genType == INNERID) { Simplex.SURFACE = false; Simplex.SOLID = true; Simplex.BOUNDARY = false; } if (genType == OUTERID) { Simplex.SURFACE = false; Simplex.SOLID = true; Simplex.BOUNDARY = true; } if (genType == BOUNDARYID) { Simplex.SURFACE = false; Simplex.SOLID = false; Simplex.BOUNDARY = true; } for (int i = 0; i < 5; i++) { interlist.add(new Vertex()); } implicit = imp; cellSize = size; cellSize2 = size2; tolerance = tol; bRep = new BoundaryRep(); minima = new cVector(); maxima = new cVector(); implicit.getBounds(minima, maxima, true); // false); // true); if (minima.x != 1E10) { System.out.println("Bounds = " + minima + " - " + maxima); //expandBounds(interval); //minima.x -= 0.1; minima.y -= 0.1; minima.z -= 0.1; //maxima.x += 0.1; maxima.y += 0.1; maxima.z += 0.1; if (interval) { x[0] = minima.x - 0.01; x[1] = maxima.x + 0.02; y[0] = minima.y - 0.03; y[1] = maxima.y + 0.04; z[0] = minima.z - 0.05; z[1] = maxima.z + 0.06; double max = x[1] - x[0]; if (max < y[1] - y[0]) { max = y[1] - y[0]; } if (max < z[1] - z[0]) { max = z[1] - z[0]; } if (max > x[1] - x[0]) { double diff = max - (x[1] - x[0]); x[1] += diff / 2; x[0] -= diff / 2; } if (max > y[1] - y[0]) { double diff = max - (y[1] - y[0]); y[1] += diff / 2; y[0] -= diff / 2; } if (max > z[1] - z[0]) { double diff = max - (z[1] - z[0]); z[1] += diff / 2; z[0] -= diff / 2; } //subdivide(x, y, z, 0); //recurse(x, y, z, 0, 0); simplexcube(x, y, z); } else { iterate(); } } Simplex.solid = null; //if (!trim) return; //System.out.println("TRIM!!"); if (genNormals) { bRep.Trim(trim, true, false, stripify, true); } else { if (tolerance == 0) { bRep.Trim(trim, false, false, stripify, true); } else { // Merge normals: tolerance == 0 means use analytic, // tolerance == 10 means use generated normals BoundaryRep analytic = (BoundaryRep) Grafreed.clone(bRep); BoundaryRep generated = (BoundaryRep) Grafreed.clone(bRep); analytic.Trim(trim, false, false, stripify, true); generated.Trim(trim, true, false, stripify, true); bRep.Trim(trim, false, false, stripify, true); // or clone System.out.println("#verticesA = " + analytic.VertexCount()); System.out.println("#verticesG = " + generated.VertexCount()); assert (bRep.VertexCount() == analytic.VertexCount()); assert (generated.VertexCount() == analytic.VertexCount()); for (int i = 0; i < bRep.VertexCount(); i++) { Vertex v = analytic.GetVertex(i); double ax = v.norm.x; double ay = v.norm.y; double az = v.norm.z; v = generated.GetVertex(i); double gx = v.norm.x; double gy = v.norm.y; double gz = v.norm.z; v = bRep.GetVertex(i); double ndn = ax * gx + ay * gy + az * gz; ndn = (ndn + 1) / 2; double t = Math.pow(ndn, tolerance * tolerance * tolerance); if (!(t > -0.0001 && t < 1.0001)) { System.out.println("t = " + t); assert (t > -0.0001 && t < 1.0001); } v.norm.x = t * ax + (1 - t) * gx; v.norm.y = t * ay + (1 - t) * gy; v.norm.z = t * az + (1 - t) * gz; v.norm.normalize(); bRep.SetVertex(v, i); } } } } private void expandBounds(boolean interval) { nCells = new int[3]; for (int i = 0; i < 3; i++) { double given = maxima.get(i) - minima.get(i); if (interval) { double width = cellSize; for (nCells[i] = 1; width < given; nCells[i] *= 2) { width *= 2; } minima.addEq(i, -(width - given) / 2); maxima.addEq(i, (width - given) / 2); } else { given += cellSize; double width = cellSize; for (nCells[i] = 1; width < given; nCells[i]++) { width += cellSize; } minima.addEq(i, -cellSize / 2); maxima.set(i, minima.get(i) + (double) nCells[i] * cellSize); } } } void iterate() { boolean grid[][][] = new boolean[nCells[0] + 1][][]; int i = 0; for (double x = minima.x; i <= nCells[0]; x += cellSize) { grid[i] = new boolean[nCells[1] + 1][]; int j = 0; for (double y = minima.y; j <= nCells[1]; y += cellSize) { grid[i][j] = new boolean[nCells[2] + 1]; int k = 0; for (double z = minima.z; k <= nCells[2]; z += cellSize) { grid[i][j][k] = implicit.inside(x, y, z, false); // true); k++; } j++; } i++; } i = 0; for (double x = minima.x; i < nCells[0]; x += cellSize) { int j = 0; for (double y = minima.y; j < nCells[1]; y += cellSize) { int k = 0; for (double z = minima.z; k < nCells[2]; z += cellSize) { if (heterogenous(grid, i, j, k)) { xc8[0] = xc8[1] = xc8[2] = xc8[3] = x; xc8[4] = xc8[5] = xc8[6] = xc8[7] = x + cellSize; yc8[0] = yc8[1] = yc8[4] = yc8[5] = y; yc8[2] = yc8[3] = yc8[6] = yc8[7] = y + cellSize; zc8[0] = zc8[2] = zc8[4] = zc8[6] = z; zc8[1] = zc8[3] = zc8[5] = zc8[7] = z + cellSize; decompose(); } k++; } j++; } i++; } } boolean heterogenous(boolean grid[][][], int i, int j, int k) { inside8[0] = grid[i][j][k]; boolean or; boolean and = or = inside8[0]; for (int m = 1; m < 8; m++) { int ii = m >= 4 ? i + 1 : i; int jj = (m / 2) % 2 != 0 ? j + 1 : j; int kk = m % 2 != 0 ? k + 1 : k; inside8[m] = grid[ii][jj][kk]; and &= inside8[m]; or |= inside8[m]; } return or && !and; } boolean heterogenous() { boolean or; boolean and = or = inside8[0]; for (int m = 1; m < 8; m++) { and &= inside8[m]; or |= inside8[m]; } return or && !and; } void subdivide(double x[], double y[], double z[], int dimension) { new Exception().printStackTrace(); System.exit(0); boolean out[] = new boolean[2]; implicit.boxInside(x, y, z, out); if (!out[0] && !out[1]) { return; } if (out[0] && out[1]) { accept(x, y, z); return; } double half[] = new double[2]; switch (dimension) { case 0: // '\0' half[0] = x[0]; half[1] = (x[0] + x[1]) / 2; subdivide(half, y, z, 1); half[0] = half[1]; half[1] = x[1]; subdivide(half, y, z, 1); break; case 1: // '\001' half[0] = y[0]; half[1] = (y[0] + y[1]) / 2; subdivide(x, half, z, 2); half[0] = half[1]; half[1] = y[1]; subdivide(x, half, z, 2); break; case 2: // '\002' half[0] = z[0]; half[1] = (z[0] + z[1]) / 2; subdivide(x, y, half, 0); half[0] = half[1]; half[1] = z[1]; subdivide(x, y, half, 0); break; } } void accept(double x[], double y[], double z[]) { xc8[0] = xc8[1] = xc8[2] = xc8[3] = x[0]; xc8[4] = xc8[5] = xc8[6] = xc8[7] = x[1]; yc8[0] = yc8[1] = yc8[4] = yc8[5] = y[0]; yc8[2] = yc8[3] = yc8[6] = yc8[7] = y[1]; zc8[0] = zc8[2] = zc8[4] = zc8[6] = z[0]; zc8[1] = zc8[3] = zc8[5] = zc8[7] = z[1]; for (int i = 0; i < 8; i++) { inside8[i] = implicit.inside(xc8[i], yc8[i], zc8[i], false); } // true); decompose(); } void recurse(double x[], double y[], double z[], int dimension, int depth) { if (depth >= 9) // mindepth3) { xc8[0] = xc8[1] = xc8[2] = xc8[3] = x[0]; xc8[4] = xc8[5] = xc8[6] = xc8[7] = x[1]; yc8[0] = yc8[1] = yc8[4] = yc8[5] = y[0]; yc8[2] = yc8[3] = yc8[6] = yc8[7] = y[1]; zc8[0] = zc8[2] = zc8[4] = zc8[6] = z[0]; zc8[1] = zc8[3] = zc8[5] = zc8[7] = z[1]; for (int i = 0; i < 8; i++) { inside8[i] = implicit.inside(xc8[i], yc8[i], zc8[i], false); } // true); if (!heterogenous()) { return; } } if (depth >= cellSize) { decompose(); return; } double half[] = new double[2]; switch (dimension) { case 0: // '\0' half[0] = x[0]; half[1] = (x[0] + x[1]) / 2; recurse(half, y, z, 1, depth + 1); half[0] = half[1]; half[1] = x[1]; recurse(half, y, z, 1, depth + 1); break; case 1: // '\001' half[0] = y[0]; half[1] = (y[0] + y[1]) / 2; recurse(x, half, z, 2, depth + 1); half[0] = half[1]; half[1] = y[1]; recurse(x, half, z, 2, depth + 1); break; case 2: // '\002' half[0] = z[0]; half[1] = (z[0] + z[1]) / 2; recurse(x, y, half, 0, depth + 1); half[0] = half[1]; half[1] = z[1]; recurse(x, y, half, 0, depth + 1); break; } } static Vector cube8 = new Vector(); void simplexcube(double x[], double y[], double z[]) { //Applet3D.tracein("simplexcube"); double cx = (x[0] + x[1]) / 2; double cy = (y[0] + y[1]) / 2; double cz = (z[0] + z[1]) / 2; //double[] cube = new double[24]; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { int index = ((i * 2 + j) * 2 + k) * 3; cube[index] = x[i]; cube[index + 1] = y[j]; cube[index + 2] = z[k]; cube3[index / 3] = new Simplex.Point(x[i], y[j], z[k]); } } } Simplex.solid = this; Simplex.Point c = new Simplex.Point(cx, cy, cz); Simplex x0a = SimplexCube(c/*x,cy,cz*/, cube, 0, 1, 2); // x = 0 Simplex x0b = SimplexCube(c/*x,cy,cz*/, cube, 1, 2, 3); Simplex y0a = SimplexCube(c/*x,cy,cz*/, cube, 0, 1, 5); // y = 0 Simplex y0b = SimplexCube(c/*x,cy,cz*/, cube, 0, 4, 5); Simplex z0a = SimplexCube(c/*x,cy,cz*/, cube, 0, 4, 2); // z = 0 Simplex z0b = SimplexCube(c/*x,cy,cz*/, cube, 2, 4, 6); Simplex x1a = SimplexCube(c/*x,cy,cz*/, cube, 4, 5, 6); // x = 1 Simplex x1b = SimplexCube(c/*x,cy,cz*/, cube, 5, 6, 7); Simplex y1a = SimplexCube(c/*x,cy,cz*/, cube, 2, 3, 7); // y = 1 Simplex y1b = SimplexCube(c/*x,cy,cz*/, cube, 2, 6, 7); Simplex z1a = SimplexCube(c/*x,cy,cz*/, cube, 1, 3, 7); // z = 1 Simplex z1b = SimplexCube(c/*x,cy,cz*/, cube, 1, 5, 7); //Vector cube8 = new Vector(); cube8.clear(); cube8.add(x0a); cube8.add(x0b); cube8.add(y0a); cube8.add(y0b); cube8.add(z0a); cube8.add(z0b); cube8.add(x1a); cube8.add(x1b); cube8.add(y1a); cube8.add(y1b); cube8.add(z1a); cube8.add(z1b); Simplex.LinkSimplex(cube8); Simplex.SetRoot(cube8); push(cube8); Subdivide(); //Simplex.SWAP = true; //System.out.println("TEMP #faces = " + bRep.faces.size()); //System.out.println("TEMP #vertices = " + bRep.vertices.size()); Simplex.GenerateTriangles(cube8); cube8.clear(); Simplex.SWAP = false; /* simplexcube0(cx,cy,cz, cube, 0,1,2); // x = 0 simplexcube0(cx,cy,cz, cube, 1,2,3); simplexcube0(cx,cy,cz, cube, 0,1,5); // y = 0 simplexcube0(cx,cy,cz, cube, 0,4,5); simplexcube0(cx,cy,cz, cube, 0,4,2); // z = 0 simplexcube0(cx,cy,cz, cube, 2,4,6); simplexcube0(cx,cy,cz, cube, 4,5,6); // x = 1 simplexcube0(cx,cy,cz, cube, 5,6,7); simplexcube0(cx,cy,cz, cube, 2,3,7); // y = 1 simplexcube0(cx,cy,cz, cube, 2,6,7); simplexcube0(cx,cy,cz, cube, 1,3,7); // z = 1 simplexcube0(cx,cy,cz, cube, 1,5,7); */ //Applet3D.traceout(); } static java.util.PriorityQueue simplexStack = new java.util.PriorityQueue(); void Subdivide() { while (simplexStack.size() > 0) // !simplexStack.empty()) { Simplex simplex = (Simplex) simplexStack.poll(); //System.out.println("Pop = " + simplex); simplex.subdivide(this); } } void simplexcube0(double cx, double cy, double cz, double[] cube, int pa, int pb, int pc) { recurseSimplex(cx, cy, cz, cube[pa * 3], cube[pa * 3 + 1], cube[pa * 3 + 2], cube[pb * 3], cube[pb * 3 + 1], cube[pb * 3 + 2], cube[pc * 3], cube[pc * 3 + 1], cube[pc * 3 + 2], 1); } Simplex SimplexCube(Simplex.Point c, // double cx, double cy, double cz, double[] cube, int pa, int pb, int pc) { return new Simplex(c, // x,cy,cz, cube3[pa], // *3], cube[pa*3 + 1], cube[pa*3 + 2], cube3[pb], // *3], cube[pb*3 + 1], cube[pb*3 + 2], cube3[pc], // *3], cube[pc*3 + 1], cube[pc*3 + 2], 0); } void recurseSimplex(double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, double dx, double dy, double dz, int depth) { //Applet3D.tracein("recurseSimplex", "(" + ax + ", " + ay + ", " + az + // "), (" + bx + ", " + by + ", " + bz + // "), (" + cx + ", " + cy + ", " + cz + // "), (" + dx + ", " + dy + ", " + dz + ")"); //if (depth >= cellSize - 3) // || depth >= cellSize) { inside[0] = implicit.inside(ax, ay, az, false); // true); inside[1] = implicit.inside(bx, by, bz, false); // true); inside[2] = implicit.inside(cx, cy, cz, false); // true); inside[3] = implicit.inside(dx, dy, dz, false); // true); boolean tryit = true; //if (false) // depth >= cellSize - 3) { if (inside[0] && inside[1] && inside[2] && inside[3]) { tryit = false; } if (!inside[0] && !inside[1] && !inside[2] && !inside[3]) { tryit = false; } } if (tryit && acceptSimplex(depth >= cellSize, ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz)) { //Applet3D.traceout(); return; } if (!tryit && depth >= cellSize2) { if (DEBUG && inside[0]) { pp.x = ax; pp.y = ay; pp.z = az; qq.x = bx; qq.y = by; qq.z = bz; rr.x = cx; rr.y = cy; rr.z = cz; ss.x = dx; ss.y = dy; ss.z = dz; double refx = (ax + bx + cx + dx) / 4; double refy = (ay + by + cy + dy) / 4; double refz = (az + bz + cz + dz) / 4; appendTriangleRef(pp, qq, rr, refx, refy, refz, true); appendTriangleRef(pp, qq, ss, refx, refy, refz, true); appendTriangleRef(pp, rr, ss, refx, refy, refz, true); appendTriangleRef(qq, rr, ss, refx, refy, refz, true); } //Applet3D.traceout(); return; } } // Subdivide double abx = (ax + bx) / 2; double aby = (ay + by) / 2; double abz = (az + bz) / 2; double acx = (ax + cx) / 2; double acy = (ay + cy) / 2; double acz = (az + cz) / 2; double adx = (ax + dx) / 2; double ady = (ay + dy) / 2; double adz = (az + dz) / 2; double bcx = (bx + cx) / 2; double bcy = (by + cy) / 2; double bcz = (bz + cz) / 2; double cdx = (cx + dx) / 2; double cdy = (cy + dy) / 2; double cdz = (cz + dz) / 2; double dbx = (dx + bx) / 2; double dby = (dy + by) / 2; double dbz = (dz + bz) / 2; //double mx = (ax + bx + cx + dx) / 4; //double my = (ay + by + cy + dy) / 4; //double mz = (az + bz + cz + dz) / 4; recurseSimplex(ax, ay, az, abx, aby, abz, acx, acy, acz, adx, ady, adz, depth + 1); recurseSimplex(bx, by, bz, abx, aby, abz, bcx, bcy, bcz, dbx, dby, dbz, depth + 1); recurseSimplex(cx, cy, cz, acx, acy, acz, bcx, bcy, bcz, cdx, cdy, cdz, depth + 1); recurseSimplex(dx, dy, dz, adx, ady, adz, cdx, cdy, cdz, dbx, dby, dbz, depth + 1); v0.x = abx; v0.y = aby; v0.z = abz; v1.x = cdx; v1.y = cdy; v1.z = cdz; //LA.vecSub(v0,v1, v2); double diag0 = LA.distance2(v0, v1); v0.x = acx; v0.y = acy; v0.z = acz; v1.x = dbx; v1.y = dby; v1.z = dbz; //LA.vecSub(v0,v1, v2); double diag1 = LA.distance2(v0, v1); v0.x = adx; v0.y = ady; v0.z = adz; v1.x = bcx; v1.y = bcy; v1.z = bcz; //LA.vecSub(v0,v1, v2); double diag2 = LA.distance2(v0, v1); int which = 0; double min = diag0; if (min > diag1) { min = diag1; which = 1; } if (min > diag2) { min = diag2; which = 2; } // Central octahedron switch (which) // depth % 3) { case 0: recurseSimplex(abx, aby, abz, cdx, cdy, cdz, bcx, bcy, bcz, dbx, dby, dbz, depth + 1); recurseSimplex(abx, aby, abz, cdx, cdy, cdz, dbx, dby, dbz, adx, ady, adz, depth + 1); recurseSimplex(abx, aby, abz, cdx, cdy, cdz, adx, ady, adz, acx, acy, acz, depth + 1); recurseSimplex(abx, aby, abz, cdx, cdy, cdz, acx, acy, acz, bcx, bcy, bcz, depth + 1); break; case 1: recurseSimplex(acx, acy, acz, dbx, dby, dbz, abx, aby, abz, adx, ady, adz, depth + 1); recurseSimplex(acx, acy, acz, dbx, dby, dbz, adx, ady, adz, cdx, cdy, cdz, depth + 1); recurseSimplex(acx, acy, acz, dbx, dby, dbz, cdx, cdy, cdz, bcx, bcy, bcz, depth + 1); recurseSimplex(acx, acy, acz, dbx, dby, dbz, bcx, bcy, bcz, abx, aby, abz, depth + 1); break; case 2: recurseSimplex(adx, ady, adz, bcx, bcy, bcz, abx, aby, abz, acx, acy, acz, depth + 1); recurseSimplex(adx, ady, adz, bcx, bcy, bcz, acx, acy, acz, cdx, cdy, cdz, depth + 1); recurseSimplex(adx, ady, adz, bcx, bcy, bcz, cdx, cdy, cdz, dbx, dby, dbz, depth + 1); recurseSimplex(adx, ady, adz, bcx, bcy, bcz, dbx, dby, dbz, abx, aby, abz, depth + 1); break; default: } /* // Vertex recurseSimplex(mx,my,mz, abx,aby,abz, acx,acy,acz, adx,ady,adz, depth + 1); recurseSimplex(mx,my,mz, abx,aby,abz, bcx,bcy,bcz, dbx,dby,dbz, depth + 1); recurseSimplex(mx,my,mz, acx,acy,acz, bcx,bcy,bcz, cdx,cdy,cdz, depth + 1); recurseSimplex(mx,my,mz, adx,ady,adz, cdx,cdy,cdz, dbx,dby,dbz, depth + 1); // Face recurseSimplex(mx,my,mz, bcx,bcy,bcz, cdx,cdy,cdz, dbx,dby,dbz, depth + 1); recurseSimplex(mx,my,mz, acx,acy,acz, cdx,cdy,cdz, adx,ady,adz, depth + 1); recurseSimplex(mx,my,mz, abx,aby,abz, adx,ady,adz, dbx,dby,dbz, depth + 1); recurseSimplex(mx,my,mz, abx,aby,abz, acx,acy,acz, bcx,bcy,bcz, depth + 1); */ //Applet3D.traceout(); } boolean acceptSimplex(boolean forced, double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, double dx, double dy, double dz) { assert false; //cVector[] triangle = new cVector[4]; //Applet3D.tracein("acceptSimplex"); int i = 0; interindex = 0; if (inside[0] ^ inside[1]) { triangle[i++] = intersect(ax, ay, az, bx, by, bz, inside[0]); } if (inside[0] ^ inside[2]) { triangle[i++] = intersect(ax, ay, az, cx, cy, cz, inside[0]); } if (inside[0] ^ inside[3]) { triangle[i++] = intersect(ax, ay, az, dx, dy, dz, inside[0]); } if (inside[1] ^ inside[2]) { triangle[i++] = intersect(bx, by, bz, cx, cy, cz, inside[1]); } if (inside[1] ^ inside[3]) { triangle[i++] = intersect(bx, by, bz, dx, dy, dz, inside[1]); } if (inside[2] ^ inside[3]) { triangle[i++] = intersect(cx, cy, cz, dx, dy, dz, inside[2]); } if (i != 3 && i != 4) //new Exception("Must have 3-4 intersections").printStackTrace(); { System.out.println("Must have 3-4 intersections: " + i); } //if (i == 3) return maxdepth; if (!forced && tolerance == 0) // + 1E-5) { ////GraphreeD.traceout(); return false; } if (i == 4 && !forced) { /* if (!coplanar(triangle[0], triangle[1], triangle[2], triangle[3])) { Applet3D.traceout(); return false; } */ simplex[0].x = ax; simplex[0].y = ay; simplex[0].z = az; simplex[1].x = bx; simplex[1].y = by; simplex[1].z = bz; simplex[2].x = cx; simplex[2].y = cy; simplex[2].z = cz; simplex[3].x = dx; simplex[3].y = dy; simplex[3].z = dz; v0.x = 0; v0.y = 0; v0.z = 0; v1.x = 0; v1.y = 0; v1.z = 0; for (int l = 0; l < 4; l++) { if (inside[l]) { v0.x += simplex[l].x / 2; v0.y += simplex[l].y / 2; v0.z += simplex[l].z / 2; } else { v1.x += simplex[l].x / 2; v1.y += simplex[l].y / 2; v1.z += simplex[l].z / 2; } } LA.vecSub(v0, v1, v2); LA.vecNormalize(v2); cVector inter = intersect(v0.x, v0.y, v0.z, v1.x, v1.y, v1.z, true); v0.x = (triangle[0].x + triangle[1].x + triangle[2].x + triangle[3].x) / 4; v0.y = (triangle[0].y + triangle[1].y + triangle[2].y + triangle[3].y) / 4; v0.z = (triangle[0].z + triangle[1].z + triangle[2].z + triangle[3].z) / 4; /* if (oppositeSide(triangle[0], triangle[1], triangle[2], triangle[3])) { v0.x = (triangle[1].x + triangle[2].x)/2; v0.y = (triangle[1].y + triangle[2].y)/2; v0.z = (triangle[1].z + triangle[2].z)/2; } else if (oppositeSide(triangle[1], triangle[0], triangle[2], triangle[3])) { v0.x = (triangle[0].x + triangle[2].x)/2; v0.y = (triangle[0].y + triangle[2].y)/2; v0.z = (triangle[0].z + triangle[2].z)/2; } else if (oppositeSide(triangle[2], triangle[0], triangle[1], triangle[3])) { v0.x = (triangle[0].x + triangle[1].x)/2; v0.y = (triangle[0].y + triangle[1].y)/2; v0.z = (triangle[0].z + triangle[1].z)/2; } else System.out.println("NO OTHER TRIANGLE"); /**/ //LA.vecSub(v0,v4, v3); //System.out.println("length = " + LA.vecLen(v3)); LA.vecSub(inter, v0, v1); //System.out.println("dot4 = " + Math.abs(LA.vecDot(v1,v2))); if (Math.abs(LA.vecDot(v1, v2)) > tolerance) // + 1E-5) { ////GraphreeD.traceout(); return false; } } if (i == 3 && !forced) { int count = 0; for (int l = 0; l < 4; l++) { if (inside[l]) { count++; } } int which; if (count == 3) // get false one { for (which = 0; which < 4; which++) { if (!inside[which]) { break; } } } else // get true one { if (count != 1) { System.out.println("COUNT != 1"); } for (which = 0; which < 4; which++) { if (inside[which]) { break; } } } simplex[0].x = ax; simplex[0].y = ay; simplex[0].z = az; simplex[1].x = bx; simplex[1].y = by; simplex[1].z = bz; simplex[2].x = cx; simplex[2].y = cy; simplex[2].z = cz; simplex[3].x = dx; simplex[3].y = dy; simplex[3].z = dz; cVector vert1 = simplex[(which + 1) % 4]; cVector vert2 = simplex[(which + 2) % 4]; cVector vert3 = simplex[(which + 3) % 4]; v2.x = (vert1.x + vert2.x + vert3.x) / 3; v2.y = (vert1.y + vert2.y + vert3.y) / 3; v2.z = (vert1.z + vert2.z + vert3.z) / 3; if (implicit.inside(v2.x, v2.y, v2.z, false /*true*/) == inside[which]) { ////GraphreeD.traceout(); return false; } cVector inter = intersect(simplex[which].x, simplex[which].y, simplex[which].z, v2.x, v2.y, v2.z, inside[which]); LA.vecSub(triangle[0], triangle[1], v0); LA.vecSub(triangle[0], triangle[2], v1); LA.vecCross(v0, v1, v2); LA.vecNormalize(v2); v0.x = (triangle[0].x + triangle[1].x + triangle[2].x) / 3; v0.y = (triangle[0].y + triangle[1].y + triangle[2].y) / 3; v0.z = (triangle[0].z + triangle[1].z + triangle[2].z) / 3; LA.vecSub(inter, v0, v1); //System.out.println("dot3 = " + Math.abs(LA.vecDot(v1,v2))); if (Math.abs(LA.vecDot(v1, v2)) > tolerance) // + 1E-5) { ////GraphreeD.traceout(); return false; } } if (!DEBUG) { appendTriangleRef(triangle[0], triangle[1], triangle[2], ax, ay, az, inside[0]); } if (!DEBUG && i == 4) { if (oppositeSide(triangle[0], triangle[1], triangle[2], triangle[3])) { appendTriangleRef(triangle[1], triangle[2], triangle[3], ax, ay, az, inside[0]); } else if (oppositeSide(triangle[1], triangle[0], triangle[2], triangle[3])) { appendTriangleRef(triangle[0], triangle[2], triangle[3], ax, ay, az, inside[0]); } else if (oppositeSide(triangle[2], triangle[0], triangle[1], triangle[3])) { appendTriangleRef(triangle[0], triangle[1], triangle[3], ax, ay, az, inside[0]); } else { System.out.println("NO OTHER TRIANGLE"); } } //Applet3D.traceout(); return true; } boolean oppositeSide(cVector point, cVector edge1, cVector edge2, cVector ref) { LA.vecSub(point, edge1, v0); LA.vecSub(ref, edge1, v1); LA.vecCross(v0, v1, v2); LA.vecSub(edge2, edge1, v3); LA.vecCross(v2, v3, v4); return (LA.vecDot(v0, v4) < 0) ^ (LA.vecDot(v1, v4) < 0); } boolean coplanar(cVector pa, cVector pb, cVector pc, cVector pd) { LA.vecSub(pa, pb, v0); LA.vecNormalize(v0); LA.vecSub(pa, pc, v1); LA.vecNormalize(v1); LA.vecCross(v0, v1, v2); LA.vecNormalize(v2); LA.vecSub(pa, pd, v3); double dist = Math.abs(LA.vecDot(v2, v3)); //System.out.println("dist = " + dist); return dist < tolerance; } cVector corners[] = new cVector[12]; void decompose() { /* boolean clockwise = false; int nCorners = 0; int edge = 0; int first = -1; int nLoops = 0; label0: do { do { if (nCorners > 12) { System.out.println("nCorners > 12"); break; } if (nLoops > 12) { System.out.println("nLoops > 12"); break; } int p = decompTable[edge][0]; int q = decompTable[edge][1]; if (inside8[p] == inside8[q]) continue label0; corners[nCorners] = intersect(xc8[p], yc8[p], zc8[p], xc8[q], yc8[q], zc8[q], inside8[p]); if (nCorners == 0) { first = edge; clockwise = inside8[p]; } nCorners++; edge = decompTable[edge][3]; } while (edge != first); break; } while (nCorners != 0 ? (edge = decompTable[edge][2]) != first : ++edge != 24); if (nCorners < 3) return; if (clockwise) { int p = 0; int q = 1; for (int r = 2; r < nCorners; r++) { appendTriangle(corners[p], corners[r], corners[q]); q++; } } else { int p = nCorners - 1; int q = p - 1; for (int r = q - 1; r >= 0; r--) { appendTriangle(corners[p], corners[r], corners[q]); q--; } } */ } Vector interlist = new Vector(); int interindex; Vertex intersect(double x1, double y1, double z1, double x2, double y2, double z2, boolean pIn) { if (!pIn) { double temp = x1; x1 = x2; x2 = temp; temp = y1; y1 = y2; y2 = temp; temp = z1; z1 = z2; z2 = temp; } Vertex result = (Vertex) interlist.get(interindex++); // new cVector(); do { result.x = 0.5 * (x1 + x2); result.y = 0.5 * (y1 + y2); result.z = 0.5 * (z1 + z2); if (Math.abs(x1 - x2) + Math.abs(y1 - y2) + Math.abs(z1 - z2) < 0.001) { return result; } if (implicit.inside(result.x, result.y, result.z, false)) // true)) { x1 = result.x; y1 = result.y; z1 = result.z; } else { x2 = result.x; y2 = result.y; z2 = result.z; } } while (true); } void appendTriangleRef(Vertex p, Vertex q, Vertex r, double refx, double refy, double refz, boolean insideref) { ref.x = refx; ref.y = refy; ref.z = refz; LA.vecSub(p, q, v0); LA.vecSub(p, r, v1); LA.vecCross(v0, v1, v2); LA.vecSub(p, ref, v1); if ((LA.vecDot(v1, v2) < 0) ^ insideref) { appendTriangle(p, q, r); } else { appendTriangle(p, r, q); } } Vertex vert = new Vertex(true); public void appendTriangle(Vertex p, Vertex q, Vertex r) { //Applet3D.tracein("appendTriangle", p + "; " + q + "; " + r); int qx; int rx; int px; // = qx = rx = -1; /* for (int i=0; i != bRep.vertices.size() && (px == -1 || qx == -1 || rx == -1); i++) { Vertex vert = (Vertex)bRep.vertices.elementAt(i); if (px == -1 && Math.abs(p.x - vert.x) + Math.abs(p.y - vert.y) + Math.abs(p.z - vert.z) < 0.1) px = i; if (qx == -1 && Math.abs(q.x - vert.x) + Math.abs(q.y - vert.y) + Math.abs(q.z - vert.z) < 0.1) qx = i; if (rx == -1 && Math.abs(r.x - vert.x) + Math.abs(r.y - vert.y) + Math.abs(r.z - vert.z) < 0.1) rx = i; } /**/ //if (px == -1) { //Vertex vert = new Vertex(); //vert.pos = new cVector(); LA.vecCopy(p, vert/*.pos*/); LA.vecCopy(p.norm, vert.norm); Vertex in = bRep.GetCache(vert); if (in != null) { px = in.index; } else { Vertex vert2 = new Vertex(true); LA.vecCopy(vert/*.pos*/, vert2/*.pos*/); LA.vecCopy(vert.norm, vert2.norm); px = bRep.VertexCount(); vert2.index = px; //bRep.AddVertex(vert2); bRep.Remember(vert2); } } //if (qx == -1) { //Vertex vert = new Vertex(); //vert.pos = new cVector(); LA.vecCopy(q, vert/*.pos*/); LA.vecCopy(q.norm, vert.norm); Vertex in = bRep.GetCache(vert); if (in != null) { qx = in.index; } else { Vertex vert2 = new Vertex(true); LA.vecCopy(vert/*.pos*/, vert2/*.pos*/); LA.vecCopy(vert.norm, vert2.norm); qx = bRep.VertexCount(); // vertices.size(); vert2.index = qx; //bRep.AddVertex(vert2); bRep.Remember(vert2); // vertextable.put(vert2, vert2); } } //if (rx == -1) { //Vertex vert = new Vertex(); //vert.pos = new cVector(); LA.vecCopy(r, vert/*.pos*/); LA.vecCopy(r.norm, vert.norm); Vertex in = bRep.GetCache(vert); if (in != null) { rx = in.index; } else { Vertex vert2 = new Vertex(true); LA.vecCopy(vert/*.pos*/, vert2/*.pos*/); LA.vecCopy(vert.norm, vert2.norm); rx = bRep.VertexCount(); vert2.index = rx; //bRep.AddVertex(vert2); bRep.Remember(vert2); } } bRep.AddFace(px, qx, rx); /* Face face = new Face(); face.p = px; face.q = qx; face.r = rx; bRep.faces.addElement(face); */ //Applet3D.traceout(); } Object3D implicit; double cellSize; double cellSize2; double tolerance; BoundaryRep bRep; int[] nCells; cVector minima; cVector maxima; static Vertex[] triangle = new Vertex[4]; static cVector[] simplex = new cVector[4]; static { for (int i = 0; i < 4; i++) { simplex[i] = new cVector(); } } static double[] cube = new double[24]; static Simplex.Point[] cube3 = new Simplex.Point[8]; private static cVector ref = new cVector(); private static cVector v0 = new cVector(); private static cVector v1 = new cVector(); private static cVector v2 = new cVector(); private static cVector v3 = new cVector(); private static cVector v4 = new cVector(); private static Vertex pp = new Vertex(); private static Vertex qq = new Vertex(); private static Vertex rr = new Vertex(); private static Vertex ss = new Vertex(); private static final double epsilon = 0.1; private static final int maxCells = 500; private static double xc8[] = new double[8]; private static double yc8[] = new double[8]; private static double zc8[] = new double[8]; private static boolean inside8[] = new boolean[8]; private static boolean inside[] = new boolean[4]; private static final int P = 0; private static final int Q = 1; private static final int Fail = 2; private static final int Succeed = 3; private static final int decompTable[][] = { { 0, 2, 1, 16 }, { 2, 3, 2, 12 }, { 3, 1, 3, 21 }, { 1, 0, 0, 9 }, { 4, 5, 5, 11 }, { 5, 7, 6, 23 }, { 7, 6, 7, 14 }, { 6, 4, 4, 18 }, { 0, 1, 9, 0 }, { 1, 5, 10, 20 }, { 5, 4, 11, 5 }, { 4, 0, 8, 17 }, { 2, 6, 13, 19 }, { 6, 7, 14, 7 }, { 7, 3, 15, 22 }, { 3, 2, 12, 2 }, { 0, 4, 17, 8 }, { 4, 6, 18, 4 }, { 6, 2, 19, 13 }, { 2, 0, 16, 1 }, { 1, 3, 21, 3 }, { 3, 7, 22, 15 }, { 7, 5, 23, 6 }, { 5, 1, 20, 10 } }; }