Search in sources :

Example 1 with Boundable

use of maspack.geometry.Boundable in project artisynth_core by artisynth.

the class FemModel3d method updateBVHierarchies.

private void updateBVHierarchies() {
    if (myAABBTree == null) {
        myAABBTree = new AABBTree();
        Boundable[] elements = new Boundable[numElements()];
        for (int i = 0; i < elements.length; i++) {
            elements[i] = myElements.get(i);
        }
        myAABBTree.build(elements, numElements());
    } else {
        myAABBTree.update();
    }
    myBVTreeValid = true;
}
Also used : AABBTree(maspack.geometry.AABBTree) Boundable(maspack.geometry.Boundable) Point(artisynth.core.mechmodels.Point)

Example 2 with Boundable

use of maspack.geometry.Boundable in project artisynth_core by artisynth.

the class FemModel3d method findContainingElement.

/**
 * Returns the element within an FEM that contains a specified
 * point, or <code>null</code> if there is no such element.
 *
 * @param pnt Point for which containing element is desired.
 * @return containing element, or null.
 */
public FemElement3d findContainingElement(Point3d pnt) {
    BVTree bvtree = getBVTree();
    ArrayList<BVNode> nodes = new ArrayList<BVNode>(16);
    bvtree.intersectPoint(nodes, pnt);
    // System.out.println ("num nodes " + nodes.size());
    if (nodes.size() == 0) {
        return null;
    }
    for (BVNode n : nodes) {
        Boundable[] elements = n.getElements();
        for (int i = 0; i < elements.length; i++) {
            if (((FemElement3d) elements[i]).isInside(pnt)) {
                return (FemElement3d) elements[i];
            }
        }
    }
    return null;
}
Also used : BVTree(maspack.geometry.BVTree) BVNode(maspack.geometry.BVNode) ArrayList(java.util.ArrayList) Boundable(maspack.geometry.Boundable) Point(artisynth.core.mechmodels.Point)

Example 3 with Boundable

use of maspack.geometry.Boundable in project artisynth_core by artisynth.

the class FemModel3d method findNearestNode.

/**
 * Finds the nearest node to a specified point that is within
 * a specified maximum distance. If no node is within the
 * specified maximum distance, <code>null</code> is returned.
 *
 * @param pnt Point for which the nearest node should be located
 * @param maxDist Maximum distance that the node must be from the
 * point. If <code>maxDist</code> &lt; 0, then <code>null</code>
 * will be returned.
 * @return Nearest point within the prescribed distance, or <code>null</code>
 * if there is no such point
 */
public FemNode3d findNearestNode(Point3d pnt, double maxDist) {
    if (maxDist < 0) {
        return null;
    }
    BVTree bvtree = getBVTree();
    ArrayList<BVNode> nodes = new ArrayList<BVNode>();
    bvtree.intersectSphere(nodes, pnt, maxDist);
    FemNode3d nearest = null;
    double dist = 1 + 2 * maxDist;
    for (BVNode n : nodes) {
        Boundable[] elements = n.getElements();
        for (int i = 0; i < elements.length; i++) {
            FemElement3d e = (FemElement3d) elements[i];
            for (int k = 0; k < e.numNodes(); k++) {
                double d = e.myNodes[k].getPosition().distance(pnt);
                if (d < dist && d <= maxDist) {
                    dist = d;
                    nearest = e.myNodes[k];
                }
            }
        }
    }
    return nearest;
}
Also used : BVTree(maspack.geometry.BVTree) BVNode(maspack.geometry.BVNode) ArrayList(java.util.ArrayList) Boundable(maspack.geometry.Boundable) Point(artisynth.core.mechmodels.Point)

Example 4 with Boundable

use of maspack.geometry.Boundable in project artisynth_core by artisynth.

the class FemMuscleModel method computeAverageFiberDirection.

/**
 * Computes the average fiber direction in the vicinity of a point based on
 * the line segments contained in a PolylineMesh. Returns the number of
 * supporting line segments used for the calculation. If no segments were
 * found, the method returns 0 and the direction is undefined.
 *
 * @param dir returns the normalized direction
 * @param pos position at which direction should be computed
 * @param rad radius of influence within which polyline mesh segments are
 * considerd
 * @param mesh mesh containing line segments used to determine the direction
 * @return number of supporting line segment
 */
public static int computeAverageFiberDirection(Vector3d dir, Point3d pos, double rad, PolylineMesh mesh) {
    BVTree bvh = mesh.getBVTree();
    ArrayList<BVNode> nodes = new ArrayList<BVNode>();
    Matrix3d cov = new Matrix3d();
    SVDecomposition3d svd = new SVDecomposition3d();
    Vector3d tmp = new Vector3d();
    Matrix3d tmp2 = new Matrix3d();
    bvh.intersectSphere(nodes, pos, rad);
    dir.setZero();
    int nsegs = 0;
    // for computing sign of direction vector
    Vector3d segmentSum = new Vector3d();
    // System.out.println("p=[");
    for (BVNode n : nodes) {
        Boundable[] elements = n.getElements();
        for (int i = 0; i < elements.length; i++) {
            LineSegment seg = (LineSegment) elements[i];
            seg = getSegmentInsideSphere(seg, pos, rad);
            if (seg != null) {
                tmp.sub(seg.myVtx1.pnt, seg.myVtx0.pnt);
                if (tmp.norm() >= 1e-8 * rad) {
                    // System.out.println(seg.myVtx0.getPosition() + " " +
                    // seg.myVtx1.getPosition());
                    nsegs++;
                    // prepare to average directions using SVD
                    computeCov(tmp2, tmp);
                    cov.add(tmp2);
                    segmentSum.add(tmp);
                }
            }
        }
    }
    if (nsegs > 0) {
        // we are technically including both +/- directions, so
        // we have twice the number of points
        cov.scale(2.0 / (2.0 * nsegs - 1));
        try {
            svd.factor(cov);
        } catch (Exception e) {
        // System.err.println(e.getMessage());
        }
        // principal components
        tmp2 = svd.getU();
        tmp2.getColumn(0, dir);
        dir.normalize();
        // most line segments
        if (dir.dot(segmentSum) < 0) {
            dir.scale(-1);
        }
        return nsegs;
    } else {
        return 0;
    }
}
Also used : BVTree(maspack.geometry.BVTree) Matrix3d(maspack.matrix.Matrix3d) SymmetricMatrix3d(maspack.matrix.SymmetricMatrix3d) Vector3d(maspack.matrix.Vector3d) BVNode(maspack.geometry.BVNode) ArrayList(java.util.ArrayList) SVDecomposition3d(maspack.matrix.SVDecomposition3d) Boundable(maspack.geometry.Boundable) IOException(java.io.IOException) LineSegment(maspack.geometry.LineSegment)

Example 5 with Boundable

use of maspack.geometry.Boundable in project artisynth_core by artisynth.

the class FemIntersector method intersectPlane.

/**
 * Intersects a FEM 3d model with a plane, returning a Polygonal mesh
 * on the plane corresponding to inside the FEM
 * @param fem model to intersect with the plane
 * @param plane plane to intersect with
 * @return intersection mesh
 */
public PolygonalMesh intersectPlane(FemModel3d fem, Plane plane) {
    AABBTree aabb = new AABBTree();
    FemElement3d[] elements = fem.getElements().toArray(new FemElement3d[fem.numElements()]);
    aabb.build(elements, fem.numElements());
    ArrayList<BVNode> nodes = new ArrayList<BVNode>();
    aabb.intersectPlane(nodes, plane);
    DirectedGraph<Point3d, Vector3d> nodeGraph = new DirectedGraph<Point3d, Vector3d>();
    TriangleIntersector ti = new TriangleIntersector();
    ti.setEpsilon(epsilon);
    for (BVNode node : nodes) {
        Boundable[] elems = node.getElements();
        for (int i = 0; i < node.getNumElements(); i++) {
            FemElement3d elem = (FemElement3d) elems[i];
            FaceNodes3d[] faceNodes = elem.getFaces();
            for (FaceNodes3d fn : faceNodes) {
                FemNode3d[][] faces = fn.triangulate();
                for (FemNode3d[] face : faces) {
                    addIfUnique(ti.intersectTrianglePlane(face[0].getPosition(), face[1].getPosition(), face[2].getPosition(), plane), nodeGraph, epsilon);
                }
            // end loop through faces
            }
        // end loop through "face nodes"
        }
    // end looping through elements
    }
    // end looping through BVNodes
    // reduceGraph(nodeGraph, tol);
    fixOverlaps(nodeGraph, epsilon);
    PolygonalMesh mesh = buildMesh(nodeGraph, plane.normal);
    removeBackFaces(mesh, plane.normal);
    nonConvexTriangulate(mesh, plane.normal, epsilon);
    return mesh;
}
Also used : ArrayList(java.util.ArrayList) TriangleIntersector(maspack.geometry.TriangleIntersector) PolygonalMesh(maspack.geometry.PolygonalMesh) DirectedGraph(maspack.graph.DirectedGraph) AABBTree(maspack.geometry.AABBTree) Vector3d(maspack.matrix.Vector3d) BVNode(maspack.geometry.BVNode) Point3d(maspack.matrix.Point3d) Boundable(maspack.geometry.Boundable)

Aggregations

Boundable (maspack.geometry.Boundable)13 BVNode (maspack.geometry.BVNode)11 ArrayList (java.util.ArrayList)10 Point (artisynth.core.mechmodels.Point)6 BVTree (maspack.geometry.BVTree)5 AABBTree (maspack.geometry.AABBTree)4 Vector3d (maspack.matrix.Vector3d)4 Face (maspack.geometry.Face)3 Point3d (maspack.matrix.Point3d)3 FemNode3d (artisynth.core.femmodels.FemNode3d)2 IOException (java.io.IOException)2 LineSegment (maspack.geometry.LineSegment)2 Vertex3d (maspack.geometry.Vertex3d)2 Matrix3d (maspack.matrix.Matrix3d)2 Point2d (maspack.matrix.Point2d)2 SVDecomposition3d (maspack.matrix.SVDecomposition3d)2 SymmetricMatrix3d (maspack.matrix.SymmetricMatrix3d)2 FemElement3d (artisynth.core.femmodels.FemElement3d)1 IntersectionPoint (maspack.collision.IntersectionPoint)1 PolygonalMesh (maspack.geometry.PolygonalMesh)1