Search in sources :

Example 1 with HalfEdge

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

the class IntersectionPoint method getTriangleEdge.

/**
 * If this intersection is degenerate and associated with one of the
 * triangle edges (but not a vertex), return that edge. Otherwise, return
 * <code>null</code>.
 *
 * @return degenerate triangle edge or <code>null</code>
 */
public HalfEdge getTriangleEdge() {
    int tedges = (intersectionCode & TRIANGLE_EDGE_MASK);
    if (tedges != 0) {
        HalfEdge he = face.firstHalfEdge();
        if (tedges == RobustPreds.E01_ON_SEGMENT) {
            return he;
        }
        he = he.getNext();
        if (tedges == RobustPreds.E12_ON_SEGMENT) {
            return he;
        }
        he = he.getNext();
        if (tedges == RobustPreds.E20_ON_SEGMENT) {
            return he;
        }
    }
    return null;
}
Also used : HalfEdge(maspack.geometry.HalfEdge)

Example 2 with HalfEdge

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

the class IntersectionPoint method getCommonEdge.

/**
 * If this point and the specified intersection point <code>p1</code>
 * are degenerate such that they both lie on a common triangle edge,
 * return that edge. Otherwise, return null. If both points lie on
 * a vertex, this method will return null as well.
 *
 * @param p1 point to query for common edge
 * @return common edge, if any
 */
public HalfEdge getCommonEdge(IntersectionPoint p1) {
    int tedges = (intersectionCode & TRIANGLE_EDGE_MASK);
    tedges &= (p1.intersectionCode & TRIANGLE_EDGE_MASK);
    HalfEdge he = face.firstHalfEdge();
    if (tedges == RobustPreds.E01_ON_SEGMENT) {
        return he;
    }
    he = he.getNext();
    if (tedges == RobustPreds.E12_ON_SEGMENT) {
        return he;
    }
    he = he.getNext();
    if (tedges == RobustPreds.E20_ON_SEGMENT) {
        return he;
    }
    return null;
}
Also used : HalfEdge(maspack.geometry.HalfEdge)

Example 3 with HalfEdge

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

the class ContactPlane method edgeEdgeContact.

/*
    * Handle the case where there are insufficient contact points in the contour
    * to define a plane. and there are no penetrating vertices in either region.
    */
boolean edgeEdgeContact(PenetrationRegion region0, PenetrationRegion region1, PolygonalMesh mesh0) {
    HashSet<HalfEdge> edges = new HashSet<HalfEdge>();
    for (IntersectionPoint mip : contour) edges.add(mip.edge);
    if (edges.size() != 2) {
        /*
          * This can happen if a penetrating vertex goes right through the other
          * object and out the other side, or if an edge is co-planar with a
          * face.
          */
        System.out.println("unknown contact type: edge-edge with " + edges.size() + " edges");
        // with "+edges.size()+" edges");
        return false;
    }
    HalfEdge edge0, edge1;
    Iterator<HalfEdge> itr = edges.iterator();
    edge0 = itr.next();
    edge1 = itr.next();
    Vector3d vedge0 = new Vector3d(), vedge1 = new Vector3d();
    vedge0.sub(edge0.getHead().getWorldPoint(), edge0.getTail().getWorldPoint());
    vedge1.sub(edge1.getHead().getWorldPoint(), edge1.getTail().getWorldPoint());
    normal.cross(vedge0, vedge1);
    normal.normalize();
    /* Compute depth=perpendicular distance between the two edges. */
    Vector3d c = new Vector3d();
    c.sub(edge1.getTail().getWorldPoint(), edge0.getTail().getWorldPoint());
    vedge0.cross(vedge0, vedge1);
    depth = Math.abs(c.dot(vedge0)) / vedge0.norm();
    minProjectedDistance = maxProjectedDistance = 0;
    checkNormalDirection(region0.getFaces(), region1.getFaces(), mesh0);
    return true;
}
Also used : Vector3d(maspack.matrix.Vector3d) HalfEdge(maspack.geometry.HalfEdge) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 4 with HalfEdge

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

the class SurfaceMeshCollider method findEdgeEdgeContacts.

/*
    * Create an edge-edge contact for each unique pair of HalfEdges where - the
    * edges are from opposite regions, - both edges are in need of edge-edge
    * correction - the geometry is suitable (see EdgeEdgeContact.calculate())
    */
public ArrayList<EdgeEdgeContact> findEdgeEdgeContacts(ContactInfo cinfo) {
    /* First scan the contours for interlocking triangles, */
    HashMap<Vertex3d, PenetratingPoint> vertexCpps = new HashMap<Vertex3d, PenetratingPoint>();
    for (PenetratingPoint cpp : cinfo.getPenetratingPoints(0)) {
        vertexCpps.put(cpp.vertex, cpp);
    }
    for (PenetratingPoint cpp : cinfo.getPenetratingPoints(1)) {
        vertexCpps.put(cpp.vertex, cpp);
    }
    ArrayList<EdgeEdgeContact> contacts = new ArrayList<EdgeEdgeContact>();
    HashMap<PenetrationRegion, PenetrationRegion> opposingRegions = cinfo.findMatchingRegions();
    for (PenetrationRegion r0 : opposingRegions.keySet()) {
        PenetrationRegion r1 = opposingRegions.get(r0);
        for (HalfEdge edge0 : r0.myEdges) {
            if (needsEdgeEdgeCorrection(edge0, vertexCpps)) {
                for (HalfEdge edge1 : r1.myEdges) {
                    if (needsEdgeEdgeCorrection(edge1, vertexCpps)) {
                        EdgeEdgeContact eec = new EdgeEdgeContact();
                        if (eec.calculate(this, edge0, edge1)) {
                            // Test the geometry to see if it is a valid edge-edge
                            // contact.
                            eec.region = r0;
                            contacts.add(eec);
                        }
                    }
                }
            }
        }
    }
    return contacts;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HalfEdge(maspack.geometry.HalfEdge)

Example 5 with HalfEdge

use of maspack.geometry.HalfEdge 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)

Aggregations

HalfEdge (maspack.geometry.HalfEdge)33 Face (maspack.geometry.Face)16 Vertex3d (maspack.geometry.Vertex3d)13 Point3d (maspack.matrix.Point3d)8 ArrayList (java.util.ArrayList)7 ContactPoint (artisynth.core.mechmodels.ContactPoint)6 Point (artisynth.core.mechmodels.Point)6 IntersectionPoint (maspack.collision.IntersectionPoint)6 Vector3d (maspack.matrix.Vector3d)6 PolygonalMesh (maspack.geometry.PolygonalMesh)5 HashSet (java.util.HashSet)4 HashMap (java.util.HashMap)3 PenetratingPoint (maspack.collision.PenetratingPoint)3 PointParticleAttachment (artisynth.core.mechmodels.PointParticleAttachment)2 BufferedWriter (java.io.BufferedWriter)2 OutputStreamWriter (java.io.OutputStreamWriter)2 PrintWriter (java.io.PrintWriter)2 NumberFormat (maspack.util.NumberFormat)2 FemElement3d (artisynth.core.femmodels.FemElement3d)1 PointAttachment (artisynth.core.mechmodels.PointAttachment)1