Search in sources :

Example 1 with Vector3i

use of maspack.matrix.Vector3i in project artisynth_core by artisynth.

the class DistanceGrid method scan.

public void scan(ReaderTokenizer rtok, Object ref) throws IOException {
    rtok.scanToken('[');
    RigidTransform3d TCL = new RigidTransform3d();
    RigidTransform3d TLW = null;
    Vector3d widths = new Vector3d();
    Vector3i resolution = null;
    myTLocalToWorld = null;
    while (rtok.nextToken() != ']') {
        if (rtok.ttype != ReaderTokenizer.TT_WORD) {
            throw new IOException("Expected attribute name, " + rtok);
        }
        if (rtok.sval.equals("resolution")) {
            rtok.scanToken('=');
            resolution = new Vector3i();
            resolution.scan(rtok);
            setResolution(resolution);
        } else if (rtok.sval.equals("widths")) {
            rtok.scanToken('=');
            widths.scan(rtok);
            setWidths(widths);
        } else if (rtok.sval.equals("center")) {
            rtok.scanToken('=');
            TCL.p.scan(rtok);
        } else if (rtok.sval.equals("orientation")) {
            rtok.scanToken('=');
            TCL.R.scan(rtok);
        } else if (rtok.sval.equals("LocalToWorld")) {
            rtok.scanToken('=');
            TLW = new RigidTransform3d();
            TLW.scan(rtok);
        } else if (rtok.sval.equals("distances")) {
            if (resolution == null) {
                throw new IOException("distances must be specified after resolution, line " + rtok.lineno());
            }
            rtok.scanToken('=');
            rtok.scanToken('[');
            int k = 0;
            while (rtok.nextToken() != ']') {
                rtok.pushBack();
                myPhi[k++] = rtok.scanNumber();
            }
        } else {
            throw new IOException("Unexpected attribute name: " + rtok);
        }
    }
    setCenterAndOrientation(TCL);
    if (TLW != null) {
        setLocalToWorld(TLW);
    }
    // clear normals and quad coefs; shouldn't be necessary if resolution
    // was set
    myQuadCoefs = null;
    clearNormals();
}
Also used : Vector3d(maspack.matrix.Vector3d) Vector3i(maspack.matrix.Vector3i) IOException(java.io.IOException)

Example 2 with Vector3i

use of maspack.matrix.Vector3i in project artisynth_core by artisynth.

the class DistanceGrid method doGetQuadDistanceAndGradient.

protected double doGetQuadDistanceAndGradient(Vector3d grad, Matrix3d dgrad, Point3d point, VectorTransformer3d quadGridToX) {
    Vector3d coords = new Vector3d();
    double[] a;
    double dx, dy, dz;
    if (storeQuadCoefs) {
        updateQuadCoefsIfNecessary();
        int voff = getQuadCellCoords(coords, null, point, quadGridToX);
        if (voff == -1) {
            return OUTSIDE_GRID;
        }
        dx = coords.x;
        dy = coords.y;
        dz = coords.z;
        a = myQuadCoefs[6 * voff + TetID.findSubTetIdx(dx, dy, dz)];
    } else {
        // Change to grid coordinates
        Vector3i vidx = new Vector3i();
        if (getQuadCellCoords(coords, vidx, point, quadGridToX) == -1) {
            return OUTSIDE_GRID;
        }
        dx = coords.x;
        dy = coords.y;
        dz = coords.z;
        a = new double[10];
        TetDesc tdesc = new TetDesc(vidx, TetID.findSubTet(dx, dy, dz));
        computeQuadCoefs(a, tdesc);
    }
    if (grad != null) {
        computeQuadGradient(grad, a, dx, dy, dz, quadGridToX);
    }
    if (dgrad != null) {
        computeQuadHessian(dgrad, a, quadGridToX);
    }
    return computeQuadDistance(a, dx, dy, dz);
}
Also used : Vector3d(maspack.matrix.Vector3d) Vector3i(maspack.matrix.Vector3i)

Example 3 with Vector3i

use of maspack.matrix.Vector3i in project artisynth_core by artisynth.

the class DistanceGrid method createQuadDistanceSurface.

/**
 * Creates a triangular mesh approximating the surface on which the
 * quadratically interpolated distance function equals <code>val</code>.
 *
 * @param val iso surface value
 * @param res multiplies the resolution of this grid to obtain the
 * resolution of the grid used to create the mesh.
 * @return iso surface for quadratic interpolation
 */
public PolygonalMesh createQuadDistanceSurface(double val, int res) {
    MarchingTetrahedra marcher = new MarchingTetrahedra();
    // sample at a res X higher resolution so we can get
    // a better sense of the smooth surface
    Vector3i cellRes = new Vector3i(getResolution());
    cellRes.scale(res);
    int nvx = cellRes.x + 1;
    int nvy = cellRes.y + 1;
    int nvz = cellRes.z + 1;
    double[] dists = new double[nvx * nvy * nvz];
    double invRes = 1.0 / res;
    Point3d q = new Point3d();
    // build a high res distance map by iterating through all the quad grid
    // cells:
    double[] a = new double[10];
    for (int i = 0; i < myQx; i++) {
        for (int j = 0; j < myQy; j++) {
            for (int k = 0; k < myQz; k++) {
                Vector3i vidx = new Vector3i(i, j, k);
                double cx, cy, cz;
                int maxci = ((i < myQx - 1) ? 2 * res - 1 : 2 * res);
                int maxcj = ((j < myQy - 1) ? 2 * res - 1 : 2 * res);
                int maxck = ((k < myQz - 1) ? 2 * res - 1 : 2 * res);
                for (int ci = 0; ci <= maxci; ci++) {
                    cx = ci * invRes / 2;
                    for (int cj = 0; cj <= maxcj; cj++) {
                        cy = cj * invRes / 2;
                        for (int ck = 0; ck <= maxck; ck++) {
                            cz = ck * invRes / 2;
                            TetDesc tdesc = new TetDesc(vidx, TetID.findSubTet(cx, cy, cz));
                            computeQuadCoefs(a, tdesc);
                            dists[(2 * i * res + ci) + (2 * j * res + cj) * nvx + (2 * k * res + ck) * nvx * nvy] = computeQuadDistance(a, cx, cy, cz);
                        }
                    }
                }
            }
        }
    }
    PolygonalMesh mesh = marcher.createMesh(dists, Vector3d.ZERO, new Vector3d(invRes, invRes, invRes), cellRes, val);
    mesh.transform(myGridToLocal);
    return mesh;
}
Also used : Vector3d(maspack.matrix.Vector3d) Vector3i(maspack.matrix.Vector3i)

Example 4 with Vector3i

use of maspack.matrix.Vector3i in project artisynth_core by artisynth.

the class DistanceGrid method doGetQuadDistance.

protected double doGetQuadDistance(Point3d point, VectorTransformer3d quadGridToX) {
    Vector3d coords = new Vector3d();
    double[] a;
    double dx, dy, dz;
    if (storeQuadCoefs) {
        updateQuadCoefsIfNecessary();
        int voff = getQuadCellCoords(coords, null, point, quadGridToX);
        if (voff == -1) {
            return OUTSIDE_GRID;
        }
        dx = coords.x;
        dy = coords.y;
        dz = coords.z;
        a = myQuadCoefs[6 * voff + TetID.findSubTetIdx(dx, dy, dz)];
    } else {
        // Change to grid coordinates
        Vector3i vidx = new Vector3i();
        if (getQuadCellCoords(coords, vidx, point, quadGridToX) == -1) {
            return OUTSIDE_GRID;
        }
        dx = coords.x;
        dy = coords.y;
        dz = coords.z;
        a = new double[10];
        TetDesc tdesc = new TetDesc(vidx, TetID.findSubTet(dx, dy, dz));
        computeQuadCoefs(a, tdesc);
    }
    return computeQuadDistance(a, dx, dy, dz);
}
Also used : Vector3d(maspack.matrix.Vector3d) Vector3i(maspack.matrix.Vector3i)

Example 5 with Vector3i

use of maspack.matrix.Vector3i in project artisynth_core by artisynth.

the class DistanceGrid method calculatePhi.

/**
 * Calculates the distance field.
 */
void calculatePhi(double[] phi, int[] closestFeatureIdxs, Feature[] features, boolean signed) {
    // Logger logger = Logger.getSystemLogger();
    // logger.info ("Calculating Distance Field...");
    double maxDist = 2 * getRadius();
    int numv = myNx * myNy * myNz;
    if (phi.length != numv || (closestFeatureIdxs != null && closestFeatureIdxs.length != numv)) {
        throw new InternalErrorException("length of phi and/or closestFeatureIdxs != numVertices()");
    }
    for (int k = 0; k < numv; k++) {
        phi[k] = maxDist;
    }
    // Feature to the grid vertex.
    if (closestFeatureIdxs != null) {
        for (int i = 0; i < numv; i++) {
            closestFeatureIdxs[i] = -1;
        }
    }
    int[] zIntersectCount = null;
    if (signed) {
        zIntersectCount = new int[numv];
        for (int i = 0; i < numv; i++) {
            zIntersectCount[i] = 0;
        }
    }
    Point3d featPnt = new Point3d();
    Point3d gridPnt = new Point3d();
    Vector3i gridMinOld = new Vector3i();
    Vector3i gridMaxOld = new Vector3i();
    Vector3i gridMin = new Vector3i();
    Vector3i gridMax = new Vector3i();
    Point3d featMin = new Point3d();
    Point3d featMax = new Point3d();
    Point3d nearPntLoc = new Point3d();
    Point3d featPntLoc = new Point3d();
    Vector3i hi = new Vector3i();
    Vector3i lo = new Vector3i();
    // For every feature ...
    for (int t = 0; t < features.length; ++t) {
        // Find the vertex-aligned parallelpiped containing the feature's
        // bounding box.
        Feature feature = features[t];
        gridMin.set(myNx + 1, myNy + 1, myNz + 1);
        gridMax.set(-1, -1, -1);
        // max, minz of the feature in grid coords
        double maxz = -INF;
        double minz = INF;
        for (int i = 0; i < feature.numPoints(); i++) {
            featPnt = feature.getPoint(i);
            myGridToLocal.inverseTransformPnt(gridPnt, featPnt);
            lo.x = clip((int) gridPnt.x, 0, myNx - 1);
            lo.y = clip((int) gridPnt.y, 0, myNy - 1);
            lo.z = clip((int) gridPnt.z, 0, myNz - 1);
            hi.x = clip((int) (gridPnt.x + 1), 0, myNx - 1);
            hi.y = clip((int) (gridPnt.y + 1), 0, myNy - 1);
            hi.z = clip((int) (gridPnt.z + 1), 0, myNz - 1);
            if (gridPnt.z < minz) {
                minz = gridPnt.z;
            }
            if (gridPnt.z > maxz) {
                maxz = gridPnt.z;
            }
            lo.updateBounds(gridMin, gridMax);
            hi.updateBounds(gridMin, gridMax);
        }
        // closestFeature.
        for (int zk = gridMin.z; zk <= gridMax.z; zk++) {
            for (int yj = gridMin.y; yj <= gridMax.y; yj++) {
                for (int xi = gridMin.x; xi <= gridMax.x; xi++) {
                    // Get features coordinates
                    featPntLoc.set(xi, yj, zk);
                    myGridToLocal.transformPnt(featPntLoc, featPntLoc);
                    // Get the distance from this point to the Feature.
                    feature.nearestPoint(nearPntLoc, featPntLoc);
                    double distance = featPntLoc.distance(nearPntLoc);
                    int index = xyzIndicesToVertex(xi, yj, zk);
                    if (index >= numv) {
                        System.out.println("coords = " + xi + " " + yj + " " + zk);
                    }
                    if (distance < phi[index]) {
                        phi[index] = distance;
                        if (closestFeatureIdxs != null) {
                            closestFeatureIdxs[index] = t;
                        }
                    }
                }
            }
        }
        if (signed) {
            if (!(feature instanceof Face)) {
                throw new IllegalArgumentException("Signed grid can only be created if all features are Faces");
            }
            Face face = (Face) feature;
            Point3d bot = new Point3d();
            Point3d top = new Point3d();
            // We're building intersectionCount[] to use in ray casting below.
            for (int yj = gridMin.y; yj <= gridMax.y; yj++) {
                for (int xi = gridMin.x; xi <= gridMax.x; xi++) {
                    Point3d ipnt = new Point3d();
                    int res = 0;
                    if (maxz >= 0) {
                        myGridToLocal.transformPnt(bot, new Point3d(xi, yj, minz - 1));
                        myGridToLocal.transformPnt(top, new Point3d(xi, yj, maxz + 1));
                        res = RobustPreds.intersectSegmentTriangle(ipnt, bot, top, face, maxDist, /*worldCoords=*/
                        false);
                    }
                    if (res > 0) {
                        myGridToLocal.inverseTransformPnt(gridPnt, ipnt);
                        int zInterval = clip((int) Math.ceil(gridPnt.z), 0, myNz - 1);
                        ++zIntersectCount[xyzIndicesToVertex(xi, yj, zInterval)];
                    }
                // point in triangle
                }
            // x
            }
        // y
        }
    }
    // Sweep, propagating values throughout the grid volume.
    for (int pass = 0; pass < 2; pass++) {
        sweep(phi, +1, +1, +1, closestFeatureIdxs, features);
        sweep(phi, -1, -1, -1, closestFeatureIdxs, features);
        sweep(phi, +1, +1, -1, closestFeatureIdxs, features);
        sweep(phi, -1, -1, +1, closestFeatureIdxs, features);
        sweep(phi, +1, -1, +1, closestFeatureIdxs, features);
        sweep(phi, -1, +1, -1, closestFeatureIdxs, features);
        sweep(phi, +1, -1, -1, closestFeatureIdxs, features);
        sweep(phi, -1, +1, +1, closestFeatureIdxs, features);
    }
    if (signed) {
        // vertex in the grid.
        for (int xi = 0; xi < myNx; xi++) {
            for (int yj = 0; yj < myNy; yj++) {
                int total_count = 0;
                // Count the intersections of the x axis
                for (int zk = 0; zk < myNz; zk++) {
                    int index = xyzIndicesToVertex(xi, yj, zk);
                    total_count += zIntersectCount[index];
                    // mesh.
                    if (total_count % 2 == 1) {
                        phi[index] = -phi[index];
                    }
                }
            }
        }
    }
}
Also used : Vector3i(maspack.matrix.Vector3i) InternalErrorException(maspack.util.InternalErrorException)

Aggregations

Vector3i (maspack.matrix.Vector3i)30 Vector3d (maspack.matrix.Vector3d)19 Point3d (maspack.matrix.Point3d)5 ArrayList (java.util.ArrayList)2 DistanceGrid (maspack.geometry.DistanceGrid)2 TetDesc (maspack.geometry.DistanceGrid.TetDesc)2 Face (maspack.geometry.Face)2 RigidTransform3d (maspack.matrix.RigidTransform3d)2 InternalErrorException (maspack.util.InternalErrorException)2 FemModel3d (artisynth.core.femmodels.FemModel3d)1 FemNode3d (artisynth.core.femmodels.FemNode3d)1 IntegrationPoint3d (artisynth.core.femmodels.IntegrationPoint3d)1 TransformableGeometry (artisynth.core.modelbase.TransformableGeometry)1 Color (java.awt.Color)1 File (java.io.File)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 TetID (maspack.geometry.DistanceGrid.TetID)1 OBB (maspack.geometry.OBB)1