Search in sources :

Example 1 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class MeshCollisionViewer method render.

public void render(Renderer renderer, int flags) {
    ContactInfo cinfo = myContactInfo;
    if (contourWidth > 0 && cinfo != null) {
        renderer.setShading(Shading.NONE);
        renderer.setLineWidth(contourWidth);
        renderer.setPointSize(contourWidth);
        renderer.setColor(contourColor, /*highlight=*/
        false);
        if (cinfo.getContours() != null) {
            for (IntersectionContour contour : cinfo.getContours()) {
                renderer.beginDraw(DrawMode.LINE_LOOP);
                for (IntersectionPoint p : contour) {
                    renderer.addVertex(p);
                }
                renderer.endDraw();
            }
        }
        Point3d pnt = new Point3d();
        renderer.beginDraw(DrawMode.POINTS);
        for (PenetratingPoint p : cinfo.getPenetratingPoints(0)) {
            pnt.set(p.vertex.pnt);
            pnt.transform(myMesh1.getMeshToWorld());
            renderer.addVertex(pnt);
        }
        for (PenetratingPoint p : cinfo.getPenetratingPoints(1)) {
            pnt.set(p.vertex.pnt);
            pnt.transform(myMesh2.getMeshToWorld());
            renderer.addVertex(pnt);
        }
        renderer.endDraw();
        renderer.setShading(Shading.FLAT);
        renderer.setLineWidth(1);
        renderer.setPointSize(1);
    }
}
Also used : IntersectionContour(maspack.collision.IntersectionContour) PenetratingPoint(maspack.collision.PenetratingPoint) IntersectionPoint(maspack.collision.IntersectionPoint) Point3d(maspack.matrix.Point3d) ContactInfo(maspack.collision.ContactInfo)

Example 2 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshContourIxer method getOneContour.

/**
 * From an non-empty list of MIPs, create a new MeshIntersectionContour and
 * return it. It might be open or closed. MIPs are removed from mips as they
 * are used.
 *
 * @param mips List of possible MeshIntersectionPoints to check. This method
 *        deletes MIPs in mips as it goes along.
 * @return new MeshIntersectionContour, or <code>null</code>
 * if <code>mips</code> is empty
 */
protected IntersectionContour getOneContour(ArrayList<IntersectionPoint> mips) throws DegenerateLoopCaseException {
    if (mips.size() == 0) {
        return null;
    }
    IntersectionContour contour = new IntersectionContour();
    contour.setClosed(true);
    IntersectionPoint firstMip = mips.get(0);
    IntersectionPoint mip = firstMip;
    IntersectionPoint nextMip = null;
    // Start the contour
    contour.add(mip);
    Face fPrev = null;
    while (nextMip != contour.get(0) || contour.size() < 2) {
        nextMip = null;
        // First search this edge's face's edges for intersection with mip.face
        Face thisEdgesFace;
        if (mip.edge.getFace() == fPrev) {
            if (mip.edge.opposite == null) {
                thisEdgesFace = null;
            } else {
                thisEdgesFace = mip.edge.opposite.getFace();
            }
        } else {
            thisEdgesFace = mip.edge.getFace();
        }
        /* 
          * We have found the edge of an open mesh. This contour is 
          * definitely open. Continue from contour.get(0) and go in 
          * opposite direction. If we already did that, then we're finished. 
          */
        if (thisEdgesFace == null) {
            if (!contour.isClosed()) {
                // We're finished, since we already did this
                break;
            }
            contour.setClosed(false);
            nextMip = firstMip;
            contour.reverse();
            mip = nextMip;
            mips.remove(mip);
            // mip.edge.getFace was already checked in first pass,
            // so we should use this as previous to switch directions.
            fPrev = mip.edge.getFace();
            continue;
        }
        /* 
          * Now the meat of the algorithm. Search this edge's faces edges
          * for another match. If found, this is the next mip in the contour
          */
        for (int i = 0; i < 3; i++) {
            HalfEdge candEdge = thisEdgesFace.getEdge(i).getPrimary();
            if (candEdge == mip.edge.getPrimary()) {
                // We already know about this edge
                continue;
            }
            EdgeFacePair testPair = new EdgeFacePair(candEdge, mip.face);
            nextMip = mySavedEdgeFaceResults.get(testPair);
            if (nextMip == null) {
                continue;
            } else {
                fPrev = thisEdgesFace;
                break;
            }
        }
        /*
          * if nextMip is still null, the next mip must be on the other mesh's face
          */
        if (nextMip == null) {
            for (int i = 0; i < 3; i++) {
                HalfEdge candEdge = mip.face.getEdge(i).getPrimary();
                EdgeFacePair testPair = new EdgeFacePair(candEdge, thisEdgesFace);
                nextMip = mySavedEdgeFaceResults.get(testPair);
                if (nextMip == null) {
                    continue;
                } else {
                    fPrev = mip.face;
                    break;
                }
            }
        }
        /*
          * If we still haven't found the next MIP at this point,
          * we're basically screwed. We should probably give up or something
          */
        if (nextMip == null) {
            System.out.println("mips.size(): " + mips.size());
            System.out.println("contour.size(): " + contour.size());
            throw new DegenerateLoopCaseException("Couldn't find next intersection point!");
        }
        mip = nextMip;
        contour.add(mip);
        if (!mips.remove(mip)) {
            // This shouldn't happen
            System.out.println("mips.size(): " + mips.size());
            System.out.println("contour.size(): " + contour.size());
            if (!contour.isClosed()) {
                System.out.println("Open contour");
            }
            throw new DegenerateLoopCaseException("Warning! nextMip wasn't in mips!!! aborting");
        }
    }
    return contour;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) HalfEdge(maspack.geometry.HalfEdge) Face(maspack.geometry.Face) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 3 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshContourIxer method findContours.

/*
    * Main interface for collision -- called by CollisionPair. Returns a
    * ContactInfo populated with the results of the collision analysis. Returns
    * null if there is no collision. mesh0, mesh1 are the candidate colliding
    * surface meshes, which can be the same mesh.
    * 
    * isRigidBodyRigidBody should be specified as true only if mesh0 and mesh1
    * both represent rigid bodies. This controls the type of data returned in
    * ContactInfo.
    */
public boolean findContours(PolygonalMesh mesh0, PolygonalMesh mesh1) {
    if (mesh0 != mesh1) {
        if (mesh0.canSelfIntersect)
            if (findContours(mesh0, mesh0))
                throw new RuntimeException("self-intersecting mesh");
        if (mesh1.canSelfIntersect)
            if (findContours(mesh1, mesh1))
                throw new RuntimeException("self-intersecting mesh");
    }
    this.mesh0 = mesh0;
    this.mesh1 = mesh1;
    double maxRadius = Math.max(RenderableUtils.getRadius(mesh0), RenderableUtils.getRadius(mesh1));
    myMaxLength = 2 * maxRadius;
    mesh0.updateFaceNormals();
    mesh1.updateFaceNormals();
    if (!mesh0.isTriangular() | !mesh1.isTriangular())
        throw new IllegalArgumentException("collision with non-triangular mesh");
    ArrayList<IntersectionPoint> allMips = new ArrayList<IntersectionPoint>();
    // Try getting allMips continuously until no DegenerateCases are caught
    boolean intersected;
    int exceptCntr = 0;
    while (true) {
        // Clear old saved results
        mySavedEdgeFaceResults.clear();
        myContours.clear();
        allMips.clear();
        BVTree bvh0 = mesh0.getBVTree();
        BVTree bvh1 = mesh1.getBVTree();
        ArrayList<BVNode> nodes0 = new ArrayList<BVNode>();
        ArrayList<BVNode> nodes1 = new ArrayList<BVNode>();
        bvh0.intersectTree(nodes0, nodes1, bvh1);
        try {
            getAllMIPs(allMips, nodes0, nodes1);
            if (allMips.size() > 0) {
                buildContours(myContours, allMips);
                intersected = true;
            } else {
                intersected = false;
            }
            return intersected;
        // break;
        } catch (DegeneratePairCaseException e) {
            System.out.println("Caught a DegeneratePairCaseException, points perturbed and retrying");
            mesh0.notifyVertexPositionsModified();
            mesh1.notifyVertexPositionsModified();
        } catch (DegenerateLoopCaseException e) {
            if (exceptCntr > 5) {
                System.out.println("SurfaceMeshContourIxer failed! Giving up after 5 tries");
                break;
            }
            System.out.println("Caught a DegenerateLoopCaseException, points perturbed and retrying");
            System.out.println(e.getMessage());
            perturbVertices(mesh0);
            perturbVertices(mesh1);
            mesh0.notifyVertexPositionsModified();
            mesh1.notifyVertexPositionsModified();
            exceptCntr++;
            continue;
        }
    }
    return false;
}
Also used : ArrayList(java.util.ArrayList) IntersectionPoint(maspack.collision.IntersectionPoint) BVTree(maspack.geometry.BVTree) IntersectionPoint(maspack.collision.IntersectionPoint) BVNode(maspack.geometry.BVNode)

Example 4 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshContourIxer method doFaceFaceCollision.

/**
 * Collide one triangular face with the second, but not the other way around.
 *
 * @param allMips new MIPs are appended to this list
 * @param f0 The face which has its edges checked
 * @param f1 The face which has its face checked
 *
 * @return the number of edge/face collisions detected in this call.
 */
protected int doFaceFaceCollision(ArrayList<IntersectionPoint> allMips, Face f0, Face f1, boolean edgeOnMesh0) {
    int numFound = 0;
    // Faces assumed to be triangular here!
    for (int eidx = 0; eidx < 3; eidx++) {
        HalfEdge e = f0.getEdge(eidx).getPrimary();
        EdgeFacePair pair = new EdgeFacePair(e, f1);
        // First check if we've already tested this edge/face pair
        if (mySavedEdgeFaceResults.containsKey(pair)) {
            if (mySavedEdgeFaceResults.get(pair) != null) {
                numFound++;
            }
            continue;
        }
        IntersectionPoint mip = new IntersectionPoint();
        boolean collided = robustIntersectionWithFace(e, f1, mip, edgeOnMesh0);
        if (collided) {
            mySavedEdgeFaceResults.put(pair, mip);
            allMips.add(mip);
            numFound++;
        } else {
            mySavedEdgeFaceResults.put(pair, null);
        }
    }
    return numFound;
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint) HalfEdge(maspack.geometry.HalfEdge) IntersectionPoint(maspack.collision.IntersectionPoint)

Example 5 with IntersectionPoint

use of maspack.collision.IntersectionPoint in project artisynth_core by artisynth.

the class SurfaceMeshIntersector method markEmptySegEnd.

void markEmptySegEnd(IntersectionPoint mip, HalfEdge edge, boolean clockwise) {
    Face face = edge.getFace();
    PolygonalMesh mesh = (PolygonalMesh) face.getMesh();
    int meshNum = (mesh == myMesh0 ? 0 : 1);
    int mark = IntersectionPoint.EMPTY_END;
    EdgeInfo einfo = getEdgeInfo(edge.getPrimary());
    if (mip.edge.getHead().getMesh() != mesh) {
        boolean tailToHead = (edge == einfo.myEdge);
        if (!clockwise) {
            tailToHead = !tailToHead;
        }
        EdgeInfo.PointData xdata = null;
        double s = einfo.project(mip);
        int idx;
        if (!tailToHead) {
            double si = 0;
            for (idx = 0; idx < einfo.numXips(); idx++) {
                double sx = einfo.getXipData(idx).s;
                if (sx - myPositionTol >= s) {
                    break;
                }
                si = sx;
            }
            if (s > si + myPositionTol) {
                mark |= IntersectionPoint.EMPTY_PROJECTED;
            }
        } else {
            double si = einfo.myUlen;
            for (idx = einfo.numXips() - 1; idx >= 0; idx--) {
                double sx = einfo.getXipData(idx).s;
                if (sx + myPositionTol <= s) {
                    break;
                }
                si = sx;
            }
            idx++;
            if (s < si - myPositionTol) {
                mark |= IntersectionPoint.EMPTY_PROJECTED;
            }
        }
        if (useEmptySegmentProjection) {
            einfo.addXip(idx, mip, s);
        }
        mip.setNearEdge(meshNum, edge);
    }
    if (useEmptySegmentProjection) {
        mip.setEmptyMark(meshNum, mark);
    }
}
Also used : IntersectionPoint(maspack.collision.IntersectionPoint)

Aggregations

IntersectionPoint (maspack.collision.IntersectionPoint)40 IntersectionContour (maspack.collision.IntersectionContour)3 HalfEdge (maspack.geometry.HalfEdge)3 ContactInfo (maspack.collision.ContactInfo)2 PenetratingPoint (maspack.collision.PenetratingPoint)2 BVNode (maspack.geometry.BVNode)2 Face (maspack.geometry.Face)2 Point3d (maspack.matrix.Point3d)2 Group (artisynth.core.mechmodels.Collidable.Group)1 Method (artisynth.core.mechmodels.CollisionBehavior.Method)1 ArrayList (java.util.ArrayList)1 ContactPlane (maspack.collision.ContactPlane)1 EdgeEdgeContact (maspack.collision.EdgeEdgeContact)1 PenetrationRegion (maspack.collision.PenetrationRegion)1 BVTree (maspack.geometry.BVTree)1 Boundable (maspack.geometry.Boundable)1 TriTriIntersection (maspack.geometry.TriTriIntersection)1 Vertex3d (maspack.geometry.Vertex3d)1 RenderObject (maspack.render.RenderObject)1 BooleanHolder (maspack.util.BooleanHolder)1